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
二维码