I am making an Android application and I want to encrypt a String before sending it to a DataBase, and encrytpion is correct. The problem happens when decrypting the String beca
getRawKey
assumes that the SecureRandom
instance is a well defined, deterministic Pseudo Random Number Generator.
First of all, it isn't well defined; the "SHA1PRNG"
method is not precisely defined. It may - and has - changed even for the SUN provider itself.
Second, the fact that seeding the SecureRandom
instance directly after construction makes it deterministic is SUN provider specific. In other words, other providers may choose to add the seed to the entropy pool. This entropy pool may have already been seeded with values obtained from the operating system. This is the case on many versions of Android. To explain it in layman terms: the Android SecureRandom
instance is fully random even if seeded directly after construction. This means that the getRawKey
method on such systems always generates a new, completely random key.
So what's the solution? The solution is either to store the key in a KeyStore
or to generate a key from a passphrase. In that case you may use the PBKDF2 (password based key derivation function #2) functionality already present in java SE and Android:
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
// note, the third argument should be set to a value as high as possible
// 10K is about the minimum nowadays
KeySpec ks = new PBEKeySpec(password, salt, 1024, 128);
SecretKey s = f.generateSecret(ks);
Key k = new SecretKeySpec(s.getEncoded(),"AES");