使用 HKDF 的目的是什么?
What is the purpose of using HKDF?
我看到了一个通过以下步骤生成 AES 密钥的代码片段:
生成一个16字节的随机值数组。
SecureRandom random = new SecureRandom();
byte[] key = new byte[16];
random.nextBytes(key);
将 HKDF 应用于密钥以生成新的加密密钥。
encrypt_key = KeyDerivation.hkdfSha256(Key,
/* inputSalt =*/ null,
hkdfInfoString.getBytes("UTF-8"),
16);
我很困惑为什么我们需要两个步骤。 SecureRandom 似乎为密钥提供了足够的熵,对吗?
两个问题:
- 我们可以直接使用 1) 中的
key
进行 AES 加密吗?
- 2) 中的空盐有什么影响?我正在考虑也许额外的步骤 2) 是为了保护密钥被泄露(只是一个猜测)。如果是,null salt 是否会使目的无效?因为我们可以预先计算HKDF的输入键material和它的输出
之间的联系
HKDF 声称盐是可选的,尽管使用随机盐确实会加强它。我很困惑什么时候需要 HKDF(尤其是没有盐)。如果我们已经有了一个具有足够熵的密钥,为什么我们需要它?如果我们有一个没有足够熵的弱密钥,HKDF(没有盐)如何帮助这种情况?我在想象攻击者可以预先计算弱密钥与生成密钥之间的映射,对吗?
- 能否直接使用1)中的密钥进行AES加密?
是的,你可以。但是,有一些原因会导致您如此频繁地更改密钥,例如算法/方案限制,不泄露(主)密钥,扩展密钥 material,派生多个密钥和/或 IV 值等......以及任何你首先需要 KBKDF 的东西( HKDF是一个基于散列的Key Based Key Derivation Function)。
但是,如果只有一个 128 位密钥派生自另一个 128 位密钥,那么我看不出有多大好处。如果您不信任 SecureRandom
实现的安全性,这可能唯一有用,因为 KDF 放置了另一层 HMAC 以在攻击者尝试猜测(显然弱)随机数生成器。
当然,正如你在问题中指出的那样,攻击者仍然可以猜测随机生成器的状态,但至少攻击者无法获得有关状态的信息通过例如反转计算或获取有关状态的统计信息。
- 2)中的null salt有什么影响?我正在考虑也许额外的步骤 2) 是为了保护密钥被泄露(只是一个猜测)。如果是,null salt 是否会使目的无效?因为我们可以预先计算出HKDF的输入键material和它的输出之间的联动
不,密钥推导函数是one-way是否存在salt。该盐用于 HKDF 的安全证明。但是,实际上并不需要提供足够的安全性。 如果您可以添加/存储/传输盐,那么它将有利于安全,但是有很多 KBKDF 一开始就(明确地)不允许使用盐。另一方面:像 PBKDF2 这样基于密码的 KDF 确实需要加盐来确保安全。
我看到了一个通过以下步骤生成 AES 密钥的代码片段:
生成一个16字节的随机值数组。
SecureRandom random = new SecureRandom(); byte[] key = new byte[16]; random.nextBytes(key);
将 HKDF 应用于密钥以生成新的加密密钥。
encrypt_key = KeyDerivation.hkdfSha256(Key,
/* inputSalt =*/ null,
hkdfInfoString.getBytes("UTF-8"),
16);
我很困惑为什么我们需要两个步骤。 SecureRandom 似乎为密钥提供了足够的熵,对吗? 两个问题:
- 我们可以直接使用 1) 中的
key
进行 AES 加密吗? - 2) 中的空盐有什么影响?我正在考虑也许额外的步骤 2) 是为了保护密钥被泄露(只是一个猜测)。如果是,null salt 是否会使目的无效?因为我们可以预先计算HKDF的输入键material和它的输出 之间的联系
HKDF 声称盐是可选的,尽管使用随机盐确实会加强它。我很困惑什么时候需要 HKDF(尤其是没有盐)。如果我们已经有了一个具有足够熵的密钥,为什么我们需要它?如果我们有一个没有足够熵的弱密钥,HKDF(没有盐)如何帮助这种情况?我在想象攻击者可以预先计算弱密钥与生成密钥之间的映射,对吗?
- 能否直接使用1)中的密钥进行AES加密?
是的,你可以。但是,有一些原因会导致您如此频繁地更改密钥,例如算法/方案限制,不泄露(主)密钥,扩展密钥 material,派生多个密钥和/或 IV 值等......以及任何你首先需要 KBKDF 的东西( HKDF是一个基于散列的Key Based Key Derivation Function)。
但是,如果只有一个 128 位密钥派生自另一个 128 位密钥,那么我看不出有多大好处。如果您不信任 SecureRandom
实现的安全性,这可能唯一有用,因为 KDF 放置了另一层 HMAC 以在攻击者尝试猜测(显然弱)随机数生成器。
当然,正如你在问题中指出的那样,攻击者仍然可以猜测随机生成器的状态,但至少攻击者无法获得有关状态的信息通过例如反转计算或获取有关状态的统计信息。
- 2)中的null salt有什么影响?我正在考虑也许额外的步骤 2) 是为了保护密钥被泄露(只是一个猜测)。如果是,null salt 是否会使目的无效?因为我们可以预先计算出HKDF的输入键material和它的输出之间的联动
不,密钥推导函数是one-way是否存在salt。该盐用于 HKDF 的安全证明。但是,实际上并不需要提供足够的安全性。 如果您可以添加/存储/传输盐,那么它将有利于安全,但是有很多 KBKDF 一开始就(明确地)不允许使用盐。另一方面:像 PBKDF2 这样基于密码的 KDF 确实需要加盐来确保安全。