创建用于 PHP 加密的 HMAC


Creating HMAC for PHP encryption

我一直在考虑将HMAC添加到PHP mcrypt加密中。

这是否只是使用加密密钥对加密数据进行哈希处理并将其附加到加密数据hash_hmac?然后在解密时,您拆分了 HMAC,再次使用密钥hash_hmac其余数据,并检查它与 HMAC 匹配。

我很困惑,因为在这个 SO 问题中 在验证密文时,应该使用 HMACed? 它说:

您必须在HMAC输入中包含影响解密过程的所有内容,即不仅是加密结果本身,还包括用于该加密的IV,并且,如果整个协议支持算法敏捷性,则还应输入加密算法的规范(否则,攻击者可以更改消息的标头,将显示" AES-256"的标记替换为显示" AES-128"的标记,然后您会在不知不觉中用错误的算法解密)。

是这样吗?如果这是真的,为什么只对加密数据使用hash_hmac还不够呢?

简短回答:是

长答案

HMAC 是基于哈希的消息身份验证代码。 您应该 HMAC 您想要进行身份验证的任何内容,或者换句话说,您想要防止被修改的任何内容。

尽管 RFC 标准更复杂,但将 HMAC 视为盐渍哈希可能是有意义的。

例如 HMAC(消息,密钥)= 哈希(消息 + 密钥)

  1. 只能使用相同的消息和密钥重新创建相同的 hmac。
  2. 如果密钥相同但消息不同,则无法重新创建相同的 hmac。
  3. 如果消息相同但密钥不同,则无法重新创建相同的 hmac。

攻击者(没有 HMAC 密钥)无法在不使现有 HMAC 失效的情况下修改部分 HMAC 消息。 它确实取决于您的数据格式和对该数据的使用,以确定 HMAC 消息和 HMAC 密钥中应包含的内容。 但是,假设您使用 HMAC 对解密进行身份验证,则应始终在 HMAC 消息中包含解密所依赖的任何内容。 对称密钥通常用作 HMAC 密钥。

在你的报价中,海报说IV和算法也应该散列。 考虑由以下部分组成的文件/数据库格式

算法 + IV + 密文 + HMAC

如果仅对密文进行 HMAC 处理,则攻击者将能够修改算法或 IV(损坏文件),而不会影响 HMAC 的有效性。 这很糟糕,因为您最终可能会得到具有有效 HMAC 的损坏的加密文件。 解密将照常进行,因为您的软件会认为一切正常。 结果是解密完全混乱,但关键是您的软件已损坏,因为它在解密时返回了错误的输出并且没有给出任何错误。 如果您的应用程序尝试对该错误数据执行某些操作,则可以将其归类为"安全风险",因为它假定它是正确的。 从某种意义上说,它不是安全风险,因为它使底层加密更弱或更容易破解。 HMAC和对称加密是两种完全不同的技术,做不同的事情。 使用 HMAC 的要点是,您可以假设解密层返回的数据是 100% 正确的。

在上面的例子中,算法是一个动态数据,我用它来解释OPs引用中的"算法敏捷性"。 它定义了使用的加密算法。 关键是它是动态的,因此需要从某个地方读取而不是硬编码。 这一事实使其成为解密的依赖项,因此应将其包含在 HMAC 消息中。 但是,如果您总是使用某些静态算法,则应由解密代码假定(硬编码到),并且无论如何都不需要存储此数据。 无需在 HMAC 消息中包含静态数据,因为它对解密没有影响。

使用静态算法的文件格式的一个例子是开源AES-256 Crypt文件格式。 算法是一致的,因此始终是假设的。 出于速度原因,它实际上使用 2 个 HMAC。1 用于验证 IV 和密钥,第 2 个用于验证加密数据部分。