Search code examples
javacryptographyshapbkdf2

PBKDF2WithHmacSHA256 impact of key length to the output length


Consider the following java code:

KeySpec spec = new PBEKeySpec("pass".toCharArray(), "salt".getBytes(),
    10000, 512);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
System.out.println(f.generateSecret(spec).getEncoded().length);

This code outputs "64". So 64 bytes, while SHA-256 is a 32 byte hash.

I know I specified 512 bits (64 byte) as the key length.
However I would expect that the generated key (PBKDF2) will be hashed by SHA-256 so that the output should always be 32 bytes, irrespective what key size I am using.

What I am missing (or why are my expectations wrong)?


Solution

  • We can write PBKDF as DK = PBKDF2(PRF, Password, Salt, c, dkLen)

    • PRF is pseudorandom function with output length hlen
    • dkLen is the desired bit-length of the derived key
    • 'c' is the number of iterations

    How it is calculated;

    DK = T1 ‖ T2 ‖ ... ‖ T_{dklen/hlen}
    

    Where Ti = F(Password, Salt, c, i) and each has hlen sizes.

    F(Password, Salt, c, i) = U1 ⊕ U2 ⊕ ... ⊕ Uc
    

    and

    U1 = PRF(Password, Salt + INT_32_BE(i))
    U2 = PRF(Password, U1)
    ...
    Uc = PRF(Password, Uc-1)
    

    The dklen can be at most 2^32 - 1 times the size of the output of the backend hash (PRF).

    as you can see, with little modification of the salt with 32-bit encoded value of i, PBKDF2 can output multiple hlen outputs.