Question

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)

Was it helpful?

Solution 2

Looks like the problem is SecureRandom not being portable across the Froyo-Gingerbread boundary. This post describes a similar problem:

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

I am not sure what exactly changed in SecureRandom, but the only way I found to fix it was to reencrypt the data with keys generated using a portable method.

OTHER TIPS

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...

According to the release notes, this fix was included in version 1.40:

PKCS7Padding validation would not fail if pad length was 0. This has been fixed.

This sounds like it may be pertinent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top