As Joachim Isaksson commented, if you want to implement a password check, you ought to use a secure hash representation of the password, that is not reversible. This way, the password can't be obtained by decryption even if the hash + key is compromised.
Anyway, in your generatePswdBasedKey
you use the PBKDF2WithHmacSHA1
algorithm to generate a SecretKey
, and then use that key to encrypt the password. Now you have two options to verify the password in checkPswdBasedKey
. Either you:
- encrypt the password the same way as in
generatePswdBasedKey
and compare that they give the same encrypted string
or you
- decrypt the encrypted version and compare the result with the password in clear.
I presume that you try the later approach as you init your cipher for decrypt with:
c.init(Cipher.DECRYPT_MODE, sk, ivParams);
Hovewer, for that approach to work you need to instantiate your SecretKey
the same way
as you did in generatePswdBasedKey
- currently you end up with two different keys.
In generatePswdBasedKey:
SecretKey sk = null;
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, IT, KEY_LENGTH);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
sk = new SecretKeySpec(keyBytes, "AES");
In checkPswdBasedKey:
byte bufferBytes[] = Base64.decode(password);
SecretKey sk = new SecretKeySpec(bufferBytes, 0, bufferBytes.length, "AES");
When that is fixed, you also need to look at your compare logic. You should not do a Base64 encoding of your result before the compare - and the compare ought to be case sensitive. Don't use:
byte result[] = c.doFinal(bufferBytes);
String resultStr = Base64.encodeToString(result, false);
if (passwordInput.equalsIgnoreCase(resultStr)) {
return true;
}
But instead use:
byte result[] = c.doFinal(bufferBytes);
String resultStr = new String(result);
if (passwordInput.equals(resultStr)) {
return true;
}