我正在创建仅可通过 tls 使用的 HTTP REST 服务。
出于身份验证目的,我计划为每个使用HMAC HS256. 我需要 HMAC 的密钥。
对密钥有什么要求?
我需要一长串随机字符吗?还是定长字符串?要不然是啥?
我正在创建仅可通过 tls 使用的 HTTP REST 服务。
出于身份验证目的,我计划为每个使用HMAC HS256. 我需要 HMAC 的密钥。
对密钥有什么要求?
我需要一长串随机字符吗?还是定长字符串?要不然是啥?
我在这里添加了我的答案,因为我觉得现有的答案不足以直接解决您的问题。
让我们看一下RFC 4868(关于 IPSec,但是它涵盖了您打算使用的 HMAC-SHA256 函数 - em mine):
块大小:底层哈希算法操作的数据块的大小。对于SHA-256,这是 512 位,对于 SHA-384 和 SHA-512,这是 1024 位。
输出长度:底层哈希算法产生的哈希值的大小。对于SHA-256,这是 256 位,对于 SHA-384,这是 384 位,对于 SHA-512,这是 512 位。
正如WhiteWinterWolf 所指出的,不鼓励超过 B(块大小),因为该值必须首先使用 SHA-256 进行散列(即在这种情况下为 512 位),并且不鼓励小于 L(输出长度)(在这种情况下为 256 位)。然而,一个 256 位的密钥是多余的,因为任何 128 位或更高的密钥都不能在任何人的当前生命周期内被暴力破解,即使世界上每台计算机都在努力破解它。
因此,我推荐使用加密安全伪随机数生成器 (CSPRNG) 生成的 128 位密钥。如果要将其存储为文本,则可以通过生成随机 32 个字符长度的十六进制字符串来表示 128 位密钥,或者您可以生成 16 个随机字节,然后通过 base64 函数运行它们。
根据RFC 7518 - JSON Web 算法 (JWA):
此算法必须使用与散列输出大小相同的密钥(例如,“HS256”为 256 位)或更大的密钥。(此要求基于 NIST SP 800-117(原文如此)[ NIST.800-107 ] 的第 5.3.4 节(HMAC 密钥的安全效果),其中规定有效安全强度是安全强度的最小值键和内部哈希值大小的两倍。)
因此,在 JWT 的情况下,您必须在 HS256 中使用至少 256 位的密钥。
定义 HMAC 函数的RFC 2104回答了这个问题:
HMAC 的密钥可以是任意长度(长于 B 字节的密钥首先使用 H 进行散列)。但是,强烈建议不要小于 L 字节,因为它会降低函数的安全强度。超过 L 字节的密钥是可以接受的,但额外的长度不会显着增加功能强度。(如果密钥的随机性被认为很弱,则建议使用更长的密钥。)
需要随机选择密钥(或使用以随机种子为种子的加密强伪随机生成器),并定期刷新。(当前的攻击并未指明密钥更改的具体推荐频率,因为这些攻击实际上是不可行的。但是,定期密钥刷新是一种基本的安全实践,有助于防止功能和密钥的潜在弱点,并限制暴露密钥的损坏。 )
有关信息,此摘录中使用了以下符号:
我们假设 H 是一个密码散列函数,其中数据通过在数据块上迭代基本压缩函数来散列。我们用 B 表示这些块的字节长度(对于所有上述哈希函数的示例,B=64),并用 L 表示哈希输出的字节长度(对于 MD5,L=16,对于 SHA-1,L=20 )。
编辑:错误的答案。未删除以保留评论线程。
长于特定散列算法块大小的 HMAC 用户输入密钥首先被缩短。(通过散列运行长键。然后使用该散列作为实际键。)
SHA256 输出 256 位哈希。那是 32 个字节。所以我建议你生成 256 位 HMAC 密钥。(使用加密安全的随机生成器。)密钥不再提供额外的安全性。