I want to store data encrypted within an Android application. Keeping an encryption key safe outside the app is not an option so I looked into password derived key algorithms.
I found a nice example from Android on the blog-post “Android Developers — Using Cryptography to Store Credentials Safely ”. Let me quote the significant code:
public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt)
throws NoSuchAlgorithmException, InvalidKeySpecException {
// Number of PBKDF2 hardening rounds to use. Larger values increase
// computation time. You should select a value that causes computation
// to take >100ms.
final int iterations = 1000;
// Generate a 256-bit key
final int outputKeyLength = 256;
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
return secretKey;
}
This method seems to imply that it's good practice to use a PIN for key derivation.
Isn't that way too easy to brute force?
In other PIN applications there is an external system that limits the number of attempts making this approach safe. In this application however I can't see how a PIN can be safe.
On a compromised system the user has the encrypted data and knows from the app/code that the pin is an $n$ digit number. So he can brute force every $10^n$ possibility and use the encrypted data to see if decryption with that derived key/pin combination returns any valid data.
Is it correct to state that password key derivation requires an alphanumeric password to be safe
Edit:
In general I understand alphanumeric passwords are better than numeric. I'm interested in feedback on my theory that I make it even easier to brute force the pin since all data except for that pin is stored on the mobile device.
I'm also looking for alternatives. Is there a way to make this safe knowing we only have a pin as secret input from the user?