首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AES BadPaddingException

AES BadPaddingException
EN

Stack Overflow用户
提问于 2011-04-08 15:03:47
回答 3查看 7.4K关注 0票数 2

如果我使用错误的密钥或错误的盐解密,就会引发BadPaddingException。我希望返回一个不正确的字符串。doFinal()会导致解密方法中的异常。

信息:This is just an example

Unfug:'ΩÙΩ„SåF?V®ßs.k˚·ºç€èÀHfif∫ÙÉÕ

代码语言:javascript
复制
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at casino.AES.decryptString(AES.java:130)
    at casino.AES.main(AES.java:172)
代码语言:javascript
复制
     public static void main(String[] args) throws Exception {
        //Encryption
        AES encr = new AES();   
        encr.setKey("KEY");
        encr.setSalt("SALT");
        encr.setup();
        String message = "This is just an example";
        System.out.println("Message : " + message);



        byte[] code = encr.encrypt(message);
        System.out.println("Encrypted Strinng : "+ new String(code, "UTF-8"));

        //Decryption
        AES dec = new AES();
        dec.setKey("INCORRECT"); //<--- incorrect 
        dec.setSalt("SALT");
        dec.setup();

        System.out.println(dec.decryptString(code));
    }




        public synchronized  void setKey(String key) throws UnsupportedEncodingException {
        this.key = key.getBytes("UTF-8");
        isPasswordAlreadySet = true;
    }


    public synchronized  void setSalt(String salt) throws UnsupportedEncodingException {
        this.salt = salt.getBytes("UTF-8");
    }

    public synchronized  void setup() throws Exception {
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    digest.update(key);
    digest.update(salt);
    byte[] raw = digest.digest();

    skeySpec = new SecretKeySpec(raw, "AES");
    cipher = Cipher.getInstance("AES");
    }  

public synchronized byte[] encrypt(byte[] klartext) throws Exception {
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

    byte[] encrypted = cipher.doFinal(klartext);

    return encrypted;
    }

    public synchronized byte[] encrypt(String klartext) throws Exception{
    return encrypt(klartext.getBytes("UTF-8")); 
    }






     public synchronized byte[] decrypt(byte[] code) throws Exception {
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] original = cipher.doFinal(code);
    return original;
    }

    public synchronized double decryptDouble(byte[] code) throws Exception {
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] original = cipher.doFinal(code);
    return doubleFromBytes( original);
    }

谢谢!弗雷德里克

EN

回答 3

Stack Overflow用户

发布于 2012-04-28 04:30:46

填充物是一种精细的健康检查。假设错误解密的数据是均匀分布的,那么每255个不正确的密码中,只会出现正确的PKCS7 5/PKCS7 7填充1次。(1/256 + 1/256^2 + 1/256^3 .)

因此,这是有帮助的,但这不是你应该依赖的东西--实际上,一个几乎8位的消息摘要并不是对数据完整性的充分测试。

还有一件事:如果攻击者可以反复修改密文并让您解密,(例如存储在cookie中的加密数据),以及当解密的数据抛出错误填充的异常时和仅仅是垃圾时,他们可以区分您的行为,那么他们就可以通过“填充oracle攻击”来确定明文。

顺便说一句,如果你真的想要你想要的行为,你可以使用"AES/CTR/NoPadding",它不需要确切的块大小,并且总是返回一个解密的byte[],不管密钥匹配与否。

票数 6
EN

Stack Overflow用户

发布于 2011-04-08 15:15:21

您应该将AES与隐式填充声明(参见可用模式)一起使用,或者强制加密/解密数据的长度(以字节为单位)为16的倍数。

此外,在默认情况下,java使用欧洲央行模式,这种模式实际上是不安全的,这取决于您使用的数据类型,您可能应该使用CBC模式。

票数 3
EN

Stack Overflow用户

发布于 2014-03-19 07:46:46

SecretKeySpec以与提供程序无关的方式指定秘密密钥。

http://themasterofmagik.wordpress.com/2014/03/19/simple-aes-encryption-and-decryption-in-java/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5596994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档