On Mon, Jan 7, 2013 at 8:18 PM, David Asta <[email protected]> wrote:
> I decided to debug it on Eclipse, and I discovered that my code only fails
> on Android 4.x. Works fine with 2.2 and 3.0. How is it possible that the
> same code doesn't work? Has really javax.crypto changed on Android 4.x?
>
It most probably fails only on 4.2 which has replaced the default
implementation of SecureRandom with an OpenSSL-based one.
See inline for details.
>
>
> The error from LogCat:
>>
>> 01-04 16:05:48.419: W/System.err(1452): javax.crypto.BadPaddingException:
>> pad block corrupted
This (usually) means that you got the wrong key.
> private static byte[] getRawKey(byte[] seed) throws Exception {
> KeyGenerator kgen = KeyGenerator.getInstance("AES");
> SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
> sr.setSeed(seed);
> kgen.init(128, sr);
> SecretKey skey = kgen.generateKey();
> byte[] raw = skey.getEncoded();
> return raw;
> }
And this is the reason it fails. This way of 'deriving' a key from a
password/seed
whatever is very wrong. It is both insecure and implementation dependent and
only worked up until now by accident. It relies on the fact that if you set the
same seed (password, etc.) to SecureRandom it will always generate the same
sequence of random numbers, which you use as a key(s). This is not really
guaranteed by the contract of the SecureRandom class, and additionally
SHA1PRNG is not exactly standardized. So, move to a proper password
derivation method such as PBKDF2. If you have old data you need to decrypt,
things get a bit more tricky: you will need to use the pre-4.2 SecureRandom
implementation for legacy data. The code below *should* work, but if doesn't
you will need to pull the
org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
class from Apache in your project and use it to derive keys for your old data.
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// alternatively, if above doesn't work
// SecureRandom sr = new SHA1PRNG_SecureRandomImpl();
// rest of your code as is
Once again, move to a proper key derivation method.
See this for more info about your particular problem:
http://stackoverflow.com/questions/13433529/android-4-2-broke-my-encrypt-decrypt-code-and-the-provided-solutions-dont-work/
And this for some background information about why you are
doing it wrong:
http://nelenkov.blogspot.jp/2012/04/using-password-based-encryption-on.html
BTW, adding SpongyCastle, etc. will not help you in this particular case.
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en