使用 HMAC 生成密钥

信息安全 密钥生成 hmac
2021-08-29 06:31:17

我正在开发一个平台,该平台将多个密钥用于多种用途:key1用于散列密码(使用 pbkdf2-hmac-sha256),key2用于生成不可重复的不可预测的 uuid(使用 aes-128 和计数器)等。

我没有存储不同的密钥,而是想从一个密钥生成它们,即:

key1 = HMAC(primary_key, "key1");
key2 = HMAC(primary_key, "key2");
...

这样做有什么严重的缺陷吗?这种编程模式很常见吗?单独生成密钥显然会带来一个小优势,即密钥之间没有数学依赖关系。但是,据我了解,即使攻击者找到key1他也无法找到primary_keykey2,对吗?

谢谢

1个回答

简短的回答:的,你是对的,你可以这样做。

但是,为了安全起见,您必须确保正确使用 HMAC 功能不会降低安全性,并且不要对所使用的功能抱有错误的期望。

根据设计,HMAC 函数期望一个参数是密钥,另一个是可以公开的消息(您可以在此处那里找到更多信息)。这意味着参数不能自由互换,确切的顺序取决于所使用的语言。

密钥是密钥:

  • 它由计算机选择的随机字符组成,
  • 其最小长度是结果哈希的长度,
  • 远程用户永远不知道,即使是其中的一部分,
  • 远程用户不能以任何方式控制或影响。

根据您的实际需要和实现,您将提供给 HMAC 函数的所有参数可能无法用作密钥:

  • primary_key 可能是您需要为其派生多个密钥的服务或域名,在这种情况下,它可能是最终用户可以访问的公共字符串,
  • keyn (key1, key2, etc.) 也可以是一个可预测的字符串,例如对应于需要为其生成密钥的内部服务。

应用于您的问题,我们有以下可能性:

  • 没有一个参数可以被视为真正安全的密钥,但其中一个是密码或等效项:如果您primary_key是用户提供的密码(即潜在的人为生成的随机字符串),您可以通过使用密码专用哈希来保持安全功能这样primary_key可能容易受到字典攻击等,但这种威胁将通过使用适当的散列函数来减轻,但会牺牲应用程序的性能(这样的散列函数被设计为很慢)。
  • 没有一个参数可以被认为是真正安全的密钥,它们甚至不包括密码:这种情况的一个例子是如果primary_key反映或从用户提供的域名中推断出来并keyn包含服务或服务器的名称(或者是从此类信息中推导出来)将为其生成最终密钥。然后将您的系统视为有缺陷的故事的结尾。您的系统错误且不安全。
  • 这些参数之一可以被视为安全密钥:注意将此参数传递给适当的参数,其中 HMAC 函数需要密钥。不这样做可能会削弱 HMAC 函数的加密强度。例如,假设它primary_key是一个服务或域名,而keyn它是一个安全密钥,与您的问题相比,您可能需要恢复您的论点:key1 = HMAC("secret_key_1", primary_key);,如有疑问,请参阅您的语言文档,
  • 这两个参数都可以被认为是安全密钥:那么你可以从这个方案中获得最高的安全性,参数可以以任何顺序传递而不会增加或降低安全性(生成的密钥将明显不同但具有相同的安全属性)。

作为旁注,HMAC RFCprimary_key还提到了截断生成的散列以减少试图从散列开始推断的攻击者可用的信息的可能性。然而,同一个 RFC 承认,虽然一些研究“显示了截断基于散列的 MAC 函数的输出的一些分析优势”,但“该领域的结果并不是绝对的”。就您的初始密钥是安全的而言,我个人感觉,由于生成的密钥较短,您在这种截断时可能会有更多的松动。在所有情况下,此 RFC 建议保留生成的哈希的最左边部分并至少保留一半。