Certification – Java – pbkdf2 and hmacsha256 as PRF
•
Java
I was given the task of creating a login API for our project. I should use pbkdf2 and hmacsha256 as PRF The plaintext password uses MD5 hash and then feeds pbkdf2 to generate the derived key The problem is that I can't get the same output as the project document tells me
This is the pbkdf2 implementation in Java:
public class PBKDF2
{
public static byte[] deriveKey( byte[] password,byte[] salt,int iterationCount,int dkLen )
throws java.security.NoSuchAlgorithmException,java.security.InvalidKeyException
{
SecretKeySpec keyspec = new SecretKeySpec( password,"HmacSHA256" );
Mac prf = Mac.getInstance( "HmacSHA256" );
prf.init( keyspec );
// Note: hLen,dkLen,l,r,T,F,etc. are horrible names for
// variables and functions in this day and age,but they
// reflect the terse symbols used in RFC 2898 to describe
// the PBKDF2 algorithm,which improves validation of the
// code vs. the RFC.
//
// dklen is expressed in bytes. (16 for a 128-bit key)
int hLen = prf.getMacLength(); // 20 for SHA1
int l = Math.max( dkLen,hLen); // 1 for 128bit (16-byte) keys
int r = dkLen - (l-1)*hLen; // 16 for 128bit (16-byte) keys
byte T[] = new byte[l * hLen];
int ti_offset = 0;
for (int i = 1; i <= l; i++) {
F( T,ti_offset,prf,salt,iterationCount,i );
ti_offset += hLen;
}
if (r < hLen) {
// Incomplete last block
byte DK[] = new byte[dkLen];
System.arraycopy(T,DK,dkLen);
return DK;
}
return T;
}
private static void F( byte[] dest,int offset,Mac prf,byte[] S,int c,int blockIndex ) {
final int hLen = prf.getMacLength();
byte U_r[] = new byte[ hLen ];
// U0 = S || INT (i);
byte U_i[] = new byte[S.length + 4];
System.arraycopy( S,U_i,S.length );
INT( U_i,S.length,blockIndex );
for( int i = 0; i < c; i++ ) {
U_i = prf.doFinal( U_i );
xor( U_r,U_i );
}
System.arraycopy( U_r,dest,offset,hLen );
}
private static void xor( byte[] dest,byte[] src ) {
for( int i = 0; i < dest.length; i++ ) {
dest[i] ^= src[i];
}
}
private static void INT( byte[] dest,int i ) {
dest[offset + 0] = (byte) (i / (256 * 256 * 256));
dest[offset + 1] = (byte) (i / (256 * 256));
dest[offset + 2] = (byte) (i / (256));
dest[offset + 3] = (byte) (i);
}
// ctor
private PBKDF2 () {}
}
I use the test vector pbkdf2-hmac-sha2 test vectors found here to verify the correctness of the implementation, and all of them are checked out I don't know why I can't get the same result using MD5 hash password
Parameters:
Salt: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F Iterations Count: 1000 DKLen: 16 (128-bit derived key)
Using "foobar" as the plaintext password, the expected results are as follows:
PWHash = MD5(PlaintextPassword) = 3858f62230ac3c915f300c664312c63f PWKey = PBKDF2(PWHash,Salt,IterationsCount,DKLen) = 33C37758EFA6780C5E52FAB3B50F329C
I got it
PWHash = 3858f62230ac3c915f300c664312c63f PWKey = 0bd0c7d8339df2c66ce4b6e1e91ed3f1
Solution
The number of iterations should be 4096, not 1000
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码
