考虑以下Java代码:
KeySpec spec = new PBEKeySpec("pass".toCharArray(), "salt".getBytes(),
10000, 512);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
System.out.println(f.generateSecret(spec).getEncoded().length);
此代码输出“ 64
”。所以是64个字节,而SHA-256是32个字节的哈希。
我知道我指定了512位(64字节)作为密钥长度。但是,我会期望生成的密钥(PBKDF2)将由SHA-256进行散列,因此输出应始终为32个字节,而不管我使用的密钥大小。
我缺少什么(或为什么我的期望错了?
我们可以将PBKDF写为DK = PBKDF2(PRF, Password, Salt, c, dkLen)
PRF
是伪随机函数,输出长度为hlen
dkLen
是派生密钥的所需位长如何计算;
DK = T1 || T2 || ... || T_{dklen/hlen}
Ti = F(Password, Salt, c, i)
的大小为hlen
。
F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc, where ^ is x-or
和
U1 = PRF(Password, Salt + INT_32_BE(i))
U2 = PRF(Password, U1)
...
Uc = PRF(Password, Uc-1)
dklen
最多为后端哈希输出大小的2 ^ 32-1倍。
如您所见,只需对32位编码值i
的salt进行少量修改,PBKDF2就可以输出多个hlen
输出。