Android密码抛出BadPaddingException,但不是在Java中
我在运行Android v20(4.4.4)的应用程序中使用了一些基本的加密 这过去是可行的,但我认为在我运行的较新版本Android中,现在出现了一个引发以下异常的错误:Android密码抛出BadPaddingException,但不是在Java中,android,encryption,Android,Encryption,我在运行Android v20(4.4.4)的应用程序中使用了一些基本的加密 这过去是可行的,但我认为在我运行的较新版本Android中,现在出现了一个引发以下异常的错误: 10-28 12:42:02.312 5173-5332/com.app W/System.err﹕ javax.crypto.BadPaddingException: pad block corrupted 10-28 12:42:02.312 5173-5332/com.app W/System.err﹕ a
10-28 12:42:02.312 5173-5332/com.app W/System.err﹕ javax.crypto.BadPaddingException: pad block corrupted
10-28 12:42:02.312 5173-5332/com.app W/System.err﹕ at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:739)
10-28 12:42:02.322 5173-5332/com.app W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1204)
10-28 12:42:02.322 5173-5332/com.app W/System.err﹕ at com.app.utils.CryptoClass.decrypt(CryptoClass.java:47)
10-28 12:42:02.322 5173-5332/com.app W/System.err﹕ at com.app.utils.CryptoClass.decrypt(CryptoClass.java:30)
方法如下:
private static byte[] decrypt(byte[] rawKey, byte[] encrypted) throws Exception {
SecretKeySpec spec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, spec);
return cipher.doFinal(encrypted); //THIS LINE THROWS EXCEPTION
}
当我运行与Java项目相同的代码时,它工作正常(使用与Android相同的Java版本1.7)
根据我在网上找到的内容,我尝试了getInstance参数的各种组合,如AES/CBC/PKCS5PADDING
,但这并不能解决问题
我正在使用的getRawKey方法:
private static byte[] getRawKey(byte[] bytes) throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "SECRET");
secureRandom.setSeed(bytes);
keygen.init(128, secureRandom);
SecretKey secretKey = keygen.generateKey();
return secretKey.getEncoded();
}
感谢您的帮助。使用
SecureRandom
派生密钥的问题在于:
使用未定义的算法,该算法可能在不同实现之间发生变化(即使来自同一供应商)SecureRandom
- 事实上,
只使用给定的种子作为熵是有缺陷的,这可能(并且确实)会因不同的实现而改变SecureRandom
“SHA1PRNG”
,这不是一个定义良好或标准化的算法,则上述情况也是正确的
在安卓系统中,Oracle提供程序中的SecureRandom
的专有功能——以及试图保持兼容的提供程序——被改为支持OpenSSL相关的提供程序。这是从4.2开始发生的。在OpenSSL中,SecureRandom
仅将给定种子混合到熵池中。换句话说,即使使用与seed相同的“密码”,也会得到一个完全随机的密钥
因此,如果您看到上面定义的
getRawKey
,请尝试将其取下。对于您自己的实现,只需使用SecretKeySpec
作为密钥,或使用PBKDF2作为密码 您是否使用了臭名昭著的getRawKey
函数,该函数试图使用种子和随机数生成器重新生成AES密钥?嗯。。。对我从一篇博客文章中复制了这个方法,这是你搜索如何做的第一个结果。实际上我正要更新这个答案,我让它工作了,但是当这个问题出现时,我不得不重新加密我试图解密的加密密钥。我使用的方法会使这个问题继续发生吗?我将把getRawKey方法添加到问题中以供参考。请注意,Cipher.getInstance(“AES”)
使用提供程序的默认操作模式和填充模式。这主要意味着ECB操作模式和PKCS#7兼容填充。PKCS#7填充是可以的(除非使用填充oracle攻击)。ECB不是,请使用CBC或-如果可用-GCM模式加密。