2

i've got the following problem. My application is divided in two different parts: 1) the first part encrypts some data using AES/CBC (Java), 2) the second part must retrieve the data and decrypt (Android). To generate the secret key i use the following code

SecureRandom saltRand = new SecureRandom(new byte[] { 1, 2, 3, 4 });
byte[] salt = new byte[16];
saltRand.nextBytes(salt);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 1024, 128);
SecretKey key = factory.generateSecret(spec);

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(key.getEncoded());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
sksCrypt = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

My program doesn't need differents "source key" (the string password), however it needs to compute the same secret key as long as source key is the same. unfortunately, the key generated by the two parts of the program are different and the decryption phase fails. Any suggestion on how to solve this issue?

1
  • The salt needs to be the same. Commented Oct 27, 2017 at 16:48

1 Answer 1

3

You are using a random key generator to generate a secret key from given input key material. Key derivation functions are functions that derive keys from secrets. There are password based key derivation functions such as PBKDF2 which use a password (plus a salt and a specific iteration count) as secret input. And there are key based key derivation functions such as HKDF that use a key and possibly a label or other output key specific information as input material.

Java does provide you with a set of PBKDF's, PBKDF1 and PBKDF2 where PBKDF2 is the newer one that you are currently using. Unfortunately it doesn't provide a KBKDF out of the box. You would need to use the (lightweight) Bouncy Castle API to do provide this kind of functionality. I know because I provided the initial implementation of the various KBKDF's for Bouncy.

Unfortunately using SecureRandom as replacement KBKDF doesn't work, as you've found out. The SHA1PRNG algorithm is not specified well; it is a function that depends on the SHA-1 secure hash function, but that's all. So implementations can and do differ, for instance between Android (which was loosely based on GNU classpath) and Oracle's Java. SHA1PRNG may or may not rely entirely on the seed. And in newer Android versions it may even be replaced by something entirely different.

As you only derive a single key from your input key material, you might as well wrap key.getEncoded() with SecretKeySpec directly and use that as a key. There is no need to perform an additional key generation at all; you already derived a key using PBKDF2. The additional wrapping doesn't do anything with the keying material. It may just be required to set the algorithm to, e.g., "AES".

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer! Since you have knowldge of the Bouncy Castle package, can you suggest me some links, documentation or whatever to start programming using its API? I've searched a lot over internet but i haven't found anything that explain its usage clearly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.