升级到1.45时BouncyCastle AES错误

最近从BC 1.34升级到1.45。 我用以下方法解码一些以前编码的数据:

SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] decrypted = cipher.doFinal(encrypted); 

当使用BC 1.45时,我得到以下exception:

 javax.crypto.BadPaddingException: pad block corrupted at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:715) at javax.crypto.Cipher.doFinal(Cipher.java:1090) 

编辑:有关此问题的更多信息。 我使用以下方法从密码短语生成原始密钥:

  KeyGenerator kgen = KeyGenerator.getInstance("AES", "BC"); SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto"); sr.setSeed(seed); kgen.init(128, sr); SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); 

我发现,这导致BC 1.34对1.45的两个不同值。

它可能也不是BouncyCastle相关的(我在Android 2.3上测试)

我刚刚跟踪了这个。 这是因为engineNextBytes()方法中SHA1PRNG_SecureRandomImpl.java的第320行(在Gingerbread源代码中)修复了错误

 bits = seedLength << 3 + 64; 

改成了

 bits = (seedLength << 3) + 64; 

很明显,这是一个被修复的错误,但这意味着在给定相同种子的情况下,SecureRandom将在姜饼前后生成不同的数据。

我有一个“修复”它。 我从android-7中窃取了足够的代码,能够以与SecureRandom相同的方式生成随机字节。 我尝试解密我的信息,如果失败,请使用我的顶级SecureRandom来解密它。 然后我可以使用更新的SecureRandom重新加密它,虽然我有点想完全放弃SecureRandom ......

看起来问题是SecureRandom无法通过Froyo-Gingerbread边界移植。 这篇文章描述了类似的问题:

http://groups.google.com/group/android-security-discuss/browse_thread/thread/6ec015a33784b925

我不确定SecureRandom究竟发生了什么变化,但我发现修复它的唯一方法是使用便携式方法生成的密钥重新加密数据。

根据发行说明 ,此修复程序包含在1.40版本中:

如果焊盘长度为0,则PKCS7Paddingvalidation不会失败。这已得到修复。

这听起来可能是相关的。