Recently upgraded from BC 1.34 to 1.45. I'm decoding some previously-encoded data with the following:
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte decrypted = cipher.doFinal(encrypted);
When using BC 1.45 I get this 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)
EDIT: More about this issue. I am using the following to generate raw keys from a passphrase:
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();
What I have found is that this results in two different values for BC 1.34 vs 1.45.
It might also not be BouncyCastle-related (I am testing on Android 2.3)
I just finished tracking this down. It's because of a bug fix on line 320 (in Gingerbread source) of SHA1PRNG_SecureRandomImpl.java in the engineNextBytes() method where
bits = seedLength << 3 + 64;
was changed to
bits = (seedLength << 3) + 64;
Clearly it was a bug that was fixed, but it means that given the same seed, SecureRandom will generate different data pre- and post-gingerbread.
I have a "fix" for it. I stole enough code from android-7 to be able to generate random bytes in the same way that SecureRandom did. I try to decrypt my information and if it fails, use my jacked up SecureRandom to decrypt it. Then I can obviously reencrypt it using the newer SecureRandom, although I'm kind of thinking of moving away from SecureRandom entirely...