Encryption Key derivation from numeric PIN?

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 saEdit:

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?

-
if n>20 it should be fine –  CodesInChaos Dec 10 '13 at 16:17

I don't see where the method implies a PIN is good practice?

This is just a wrapper function for a key derivation function, and the variable names chosen to say "This is the one that contains the not-very-random-data". Obviously more entropy the passphraseOrPin variable has the better, but it might just be that for use-ability's sake a designer only uses a PIN.

-
I modified the original text in my question to "seems to imply" since you have a point there. However if a PIN code is a NO GO on Android where the data itself is always retrievable (root, hence the need for encryption) then I would still think of this as a bad name for an example. –  hcpl Dec 10 '13 at 15:59
Well, simply a passphrase need not be very secure (ie 'password'), and concievably a PIN might be mandated to be something more than just 4 decimal digits? 8 random hex characters would be much better than many things a user can be trusted to come up with! –  figlesquidge Dec 10 '13 at 16:09

It is common that the attacker has at least as fast platform as somebody generating the key. Thus, brute force attacker can test all 4 digit PINs in 1000 seconds or 17 minutes (based on 100 ms seconds mentioned in the question).

BTW, it is fairly common to use larger iteration counts than minimum of 1000 and longer times (like anything that takes 1s to process. On modern platforms, counts of 10000 or 100000 can be completely reasonable). In addition, it is common to punish wrong attempts with delay to slow down guessing.

In case the attacker has access to some computing power, like ASIC circuitry designed for cracking PBKDF2, they may be able to break the secret, for instance, 1000 times faster i.e, the could guess 10000 pins/passwords per second (assuming key derivation takes 100 ms seconds on the device).

--

For PIN and PBKDF2 to be secure against attacks, it is often mandatory to do these:

• Attacker cannot get direct access to the storage on the device (to get values needed for breaking the secret offline with specialized devices)
• The device does not allow to try many PINs very quickly (increasing delay after trying).
• Too many miss attempts lock the device.

But, generally using good passwords is much more secure than using PIN codes. This is my earlier answer on security of PIN or password when materials needed for brute forcing are available for the attacker.

-
Thank you for this answer. The second part interests me the most. However since this is mobile we can not guarantee the device itself will not be compromised. Also this encryption is local only so all data would be available to the hacker except for the users password. It's obvious from the gui that this password is a 5 number digit. Even worse is that that digit is needed for authentication elsewhere. By using this for encryption my fear is that we give that pin away since brute force is so easy. –  hcpl Dec 11 '13 at 6:52