【问题标题】:PHP mcrypt_decrypt - can I determine if data is decrypted with the right key?PHP mcrypt_decrypt - 我可以确定数据是否用正确的密钥解密?
【发布时间】:2011-11-09 16:42:44
【问题描述】:

我正在编写一个 php 脚本,并正在使用 mcrypt 加密/解密任意数据。

当我使用另一个密钥解密加密数据时(例如,我输入了错误的密码),输出当然不会被正确解密。

如果使用了错误的键,我想显示一条错误消息,但我认为很难将输出字符串验证为正确的“纯文本”(因为编码数据中的字符也可以作为输入有效)数据)。

有没有办法解决这个问题?


在我写这个问题的时候,我有了一个想法:)

我是否可以在输入数据前加上一个静态“控制”字符串,并在解密时使用它进行验证?

【问题讨论】:

  • 你有没有想过在解密之前使用哈希来验证密钥?
  • 编辑:我没有保存密钥的任何校验和(在数据库等中),所以在我的情况下不能这样做吗?
  • 基本上,除了加密数据之外,您还存储原始密钥的哈希值。然后在使用给定密钥解密加密数据之前,使用相同的哈希算法计算给定密钥的哈希值,并将结果与​​存储的哈希值进行比较。如果散列相同,则键也(很可能)相同。 (另见integrity verification using cryptographic hash functions
  • 我不建议在加密数据之外存储密钥的哈希值。如果攻击者可以对哈希进行尝试而不是解密整个文件,那么攻击者可以更容易地使用暴力破解密码。

标签: php validation mcrypt


【解决方案1】:

为您的加密数据添加完整性的最佳方法是添加仅在加密数据上创建的 MAC。

不要在纯文本上应用 MAC,因为 MAC 可以揭示有关该文本的一些信息。创建 MAC 不是为了提供安全性 - 只是为了完整性。

所以,正确的算法应该是 ENCRYPT-THEN-MAC!

更多详细信息请参阅此视频http://d396qusza40orc.cloudfront.net/crypto/recoded_videos%2F7.4%20%5B974a4c90%5D%20.mp4

【讨论】:

    【解决方案2】:

    我通常这样做:

    • 散列输入数据(文件或消息等)。
    • 加密数据。
    • 在加密数据前面加上 IV 和数据的哈希值。
    • 发送或存储 IV + 哈希 + 密文。

    由于 IV 和哈希总是相同的长度,因此无需添加填充或控制字符。

    在接收端或读取端:

    • 提取 IV。
    • 提取哈希。
    • 提取和解密加密文本。
    • 对解密后的数据进行散列,并检查它是否与提取的散列匹配。

    因此,您存储的是源数据的散列,而不是键的散列。正如上面发布的评论者所说,泄露您的密钥哈希是一个漏洞,因为攻击者现在只需要在彩虹表中搜索它(它会在几秒钟内破坏您的数据)。

    您存储控制字符串的想法也很好(当然更快),但它不能让您确认消息或数据确实未损坏,只能确认使用了正确的密钥。

    【讨论】:

    • 另一种方法是在对原始数据进行编码之前将哈希添加到原始数据中。这是我使用的:gist.github.com/3965357
    • 是的,这是另一种方式。只要“控制参考”字符串只能与正确的加密密钥恢复或匹配(或两者),它就会起作用。即使使用您的链接代码,它实际上只使用了一小部分哈希。 (但是,我想知道为什么您只使用哈希中的四个字节;哈希越短,冲突的可能性就越高。您的应用程序中可能存在空间/大小限制?)
    • 即使有 4 个字节的冲突概率也是 1/14^4 - 对于 100 万条记录数据库来说已经足够了。毕竟,数据必须是一致的。如果是 - 那么它是正确的,否则它根本不会解密。例如,在我的场景中,如果解密成功与否,我将其用于评估。如果是 - 那么我认为它是一致的。附:关于碰撞的另一个例子是 clickbank 收据编号。他们只有 8 个字符,足以记录他们所有销售的所有历史。问候,安东。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 2012-11-10
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多