【问题标题】:Creating HMAC for PHP encryption为 PHP 加密创建 HMAC
【发布时间】:2015-03-06 04:23:39
【问题描述】:

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

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

我很困惑,因为在这个 SO 问题 When authenticating ciphertexts, what should be HMACed? 中它说:

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

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

【问题讨论】:

    标签: php encryption


    【解决方案1】:

    简答:是的

    长答案

    HMAC是基于Hash的消息认证码。你应该 HMAC 任何你想要验证的东西,或者换句话说,任何你想要防止被修改的东西。

    虽然the RFC standard 更复杂,但将 HMAC 视为加盐哈希可能是有意义的。

    例如hmac(message, key) = hash(message + key)

    1. 您可以使用相同的消息和密钥重新创建相同的 hmac。
    2. 如果密钥相同但消息不同,您不能重新创建相同的 hmac。
    3. 如果消息相同但密钥不同,您不能重新创建相同的 hmac。

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

    在您的报价中,发帖人说 IV 和算法也应该被散列。考虑由

    组成的文件/数据库格式

    算法 + IV + 密文 + HMAC

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

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

    使用静态算法的文件格式示例是the open source AES-256 Crypt File Format。该算法是一致的,因此总是假设的。出于速度原因,它实际上使用了 2 个 HMAC。 1 验证 IV 和密钥,2 验证加密数据部分。

    【讨论】:

    • 如果加密库检查填充的所有字节,仍然可以检查解密是否成功。如果填充中甚至有一个错误,它可能会抛出异常或类似的东西。如果 HMAC 已损坏,您将无法进行解密。
    • 根据使用的填充,通过检查有效填充的身份验证几乎总是不如使用 hmac 可靠。即使解密错误,它也可能会随机创建一个有效的填充。
    • “这很糟糕,因为您最终会得到一个带有有效 HMAC 的损坏的加密文件。”不过,这不会造成任何安全风险,不是吗?
    • 如何使用加密/解密层在这里很重要。通常,假设在软件中是不好的。如果您的应用程序代码假设解密成功并作用于错误数据,那么它可能是无害的,也可能是非常糟糕的。它是否是“安全风险”取决于您的定义,但它肯定会被归类为存在于加密/解密层的问题。但是,不,如果这就是您所要求的,这不是一种安全风险,它可以更容易地破解底层加密。
    • 没问题。我试图将我们在这里讨论的所有内容都结合起来。谢谢
    猜你喜欢
    • 2017-09-05
    • 2014-07-02
    • 2012-09-08
    • 2015-08-22
    • 2016-11-23
    • 1970-01-01
    • 2017-01-31
    • 2020-11-06
    • 1970-01-01
    相关资源
    最近更新 更多