views:

383

answers:

3

Hi everybody, im doing password based file encryption in Java. Im using AES as the underlying encryption algorithm and PBKDF2WithHmacSHA1 to derive a key from a salt and password combination using the following code(which i got from another generous poster on this site).

SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec ks = new PBEKeySpec(password,salt,1024,128);
SecretKey s = f.generateSecret(ks);
Key k = new SecretKeySpec(s.getEncoded(),"AES");

I share the salt, the user enters their password at each end and encrytion and decryption work fine :-) My problem is that i would like to be able to verify that the password the user enters is correct before embarking on the (potentialy long) decrytpion process. I know the PBKD spec includes an optional 2 byte verification value but im not sure how to generate this value using the above approach. Does java provide support for this or if not what would be a secure alternative?

Thanks for your time.

+1  A: 

There is no "quick check" mechanism that is secure, by definition. The whole point of using PBKDF2 or related techniques is to make password checking slow, to foil password cracking programs. If you added a quick check system, password crackers would be able to guess passwords in bulk very quickly.

Chris Jester-Young
Hi, thanks for your answere. I was under the impression that the purpose of PBKDF2 and its repeated combining of salt and password to derive the key was to make the process of computing the key from the plain text password expensive and therefor make dictionary style attacks harder. Like i said the PBKDF2 spec includes an optional password verification value, i just dont know how to get at it in the java implementation.
I agree that allowing a quick check after the key derivation process process is complete makes a brute force attack easyer since the attacker need not actually decrypt anything to check there key, but i would have thought the large search space of 256-bit AES keys makes a pure brute force attack prohibitive anyway?
@pinkynobrain: The problem with the quick check is that it shrinks the key space a lot: you have a quick way to find out all the passphrases for which the quick check succeeds. Therefore, you have much fewer keys to brute force the AES with.
Chris Jester-Young
A: 

Compute some sort of password verification tag and store that alongside the encrypted file data so that you can check it first. This might be something like the PBMAC of a fixed (short) string. Of course, this needs to be a non-reversible function so a cracker could not determine the password, and not be too quick to compute so as to confound the brute force attack.

Have you considered whether (and how) you will detect if the whole file has been decrypted correctly? You should probably look into some combination of PBES2 and PBMAC rather than using AES directly.

crazyscot
Hi, thanks for your quick response and your advice on PBES2 and PMAC, i'll definetly look into that. I had thought of using the fixed string approach but was worried it opens up the process to known plain text attacks. Instead i thought of using a secure hash of the key itself, if the hash function is truly non invertable then this would provide no info on the key itself but would still allow me to check the keys are the same. What do you reckon, is this a good approach?
It's true that some sort of verification necessarily makes a known plaintext of sorts. However the use of the PB* functions makes the work function harder, effectively multiplying it by your iteration count when compared with a naive single hash.
crazyscot
+1  A: 

Hey, thanks to crazy scot and Chris for there help. After doing some digging i decided to use the methods described on Dr Gladmans file encryption page for doing both password verification and message authentication. I believe this method, based on the PBKDF2 and a MAC, makes deriving the verfication value for m the password sufficiently expensive as to make it secure. Thanks again, and i hope this solution aids others.