【问题标题】:PBKDF2WithHmacSHA256 impact of key length to the output lengthPBKDF2WithHmacSHA256 密钥长度对输出长度的影响
【发布时间】:2020-02-18 21:11:38
【问题描述】:

考虑下面的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 字节,无论我使用什么密钥大小。

我缺少什么(或者为什么我的期望是错误的)?

【问题讨论】:

  • PBKDF2 的一个主要特点,尤其是与现在改名为 PBKDF1 的前身相比,它的输出几乎可以是任意大小,尤其是大于底层哈希的输出。
  • @dave_thompson_085 我同意。但是我选择了 PBKDF2WithHmacSHA256 变体,所以我希望我总是从输出中得到一个 SHA256(32 字节)。情况似乎并非如此。为什么?
  • @MRalwasser:你说你同意,但你忽略了“......尤其是大于底层哈希的输出”。

标签: java cryptography sha pbkdf2


【解决方案1】:

我们可以将PBKDF写成DK = PBKDF2(PRF, Password, Salt, c, dkLen)

  • PRF 是输出长度为hlen 的伪随机函数
  • dkLen 是派生密钥所需的位长
  • 'c' 是迭代次数

如何计算;

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

其中Ti = F(Password, Salt, c, i) 和每个都有hlen 大小。

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

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

dklen 最多可以是后端哈希 (PRF) 输出大小的 2^32 - 1 倍。

如您所见,只需对 32 位编码值 i 的 salt 进行少量修改,PBKDF2 就可以输出多个 hlen 输出。

【讨论】:

  • 感谢您的解释,但我在您的回答中遗漏了 SHA256 部分,这是我问题中的关键部分。按照您的功能定义,看起来 PBKDF2WithHmacSHA256 可以写为 SHA256(PBKDF2(..)) 的函数。这是真的吗?如果是,为什么输出长度不总是 256 位?
  • 表示使用HmacSHA256hlen位大小为32字节。现在,如果您要求更多,dkLen PBKDF2 将生成 T2、T3、.. 以生成所需长度的密钥,直到 2^32 - 1 * hLen
  • 所以 PRF 在我的情况下是 SHA256?
  • HMACSHA256 是您的 PRF。 HMAC 使用 SHA256。
  • 谢谢,我不知道 HMACSHA256 函数实际上是 PBKDF2 的输入参数。我认为它处理了 PBKDF2 的输出。谢谢!
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多