【问题标题】:Encryption: Testing that a string is properly decrypted?加密:测试字符串是否被正确解密?
【发布时间】:2011-07-02 05:48:03
【问题描述】:

这是一个理论,它不仅适用于 PHP,而且可能适用于更多语言。

假设我使用mcrypt 库和AES-256 密码加密了一个字符串。加密后的字符串现在看起来类似于þøÆ{”ò(ü´îÚÜÇW¹ËŸK­¯L‘rø?ª¶!JF£­º+Œ’Ú'‚

如果加密密钥在解密和加密事件之间发生变化,那么解密的结果显然毫无价值。
由于加密字符串至少对我来说包含随机字符,因此对其进行某种测试以确保它处于加密/解密状态并不容易。

我花了一些时间思考。 如何测试字符串是否已正确解密?
如果我在加密之前给原始字符串附加一个小前缀,然后在解密时删除这个前缀会怎样。如果没有找到这个前缀,就可以说解密失败了。

这是处理这个问题的合适方法吗?

【问题讨论】:

  • 您可以包含明文的哈希值(例如 sha-1),而不是简单的前缀。这样您就可以获得完整性检查作为奖励。
  • @Code 这是个好主意。哈希必须后跟一个定义的字符来标记边界
  • 关于你的方法,如果你能找到一个字符串 $a 使得对于每个可能的字符串 $b,$a 的编码是安全的。 $b 永远不会以 $a 开头。
  • 为什么需要一个已定义的字符?典型的散列具有恒定的大小。例如,一个 sha-1 哈希只有 20 个字节。
  • @CodeInChaos 如果加密的字符串相当大,甚至是文件/文档,那是个好主意。我怀疑在小字符串上实现是个好主意

标签: php encryption aes mcrypt


【解决方案1】:

要测试数据完整性,您需要Message Authentication Code (MAC)。

有一些独立的 MAC 算法,看起来像一个带有密钥的哈希函数。非常标准的 MAC 算法是HMAC(它使用哈希函数)。

由于您还加密了数据,因此您需要使用内置 MAC 的加密模式;有一些这样的模式,例如GCMEAX。这些模式适用于分组密码,通常是AES

在加密前给数据加上一个已知的前缀或后缀就是自制的MAC。 MAC 很微妙,容易出错。例如,如果您添加一个 CRC32,然后使用流密码(或 CTR 模式下的分组密码)进行加密,那么您正在复制the seven capital sins of WEP 之一(具体参见第 4 节,关于 CRC32-as-MAC 问题) .基本上你的完整性检查不再能抵抗主动攻击;您只是在检测无辜的错误,例如使用错误的密钥。

(不幸的是,MCrypt 似乎不支持任何组合加密/MAC 模式。PHP 本身在使用 --with-mhash 选项编译时,提供了实现原始哈希和 HMAC 的 mhash() 函数。)

【讨论】:

  • 嗨,托马斯。感谢您的广泛回答。我需要一些时间来消化它!关于 PHP 中的 mhash() 函数 - 它已被 hash() 取代,在这种情况下(?)hash_hmac php.net/manual/en/function.hash-hmac.php
  • 快速入门:为什么如您所说,MAC 的微妙和容易出错?
  • @Industrial:概念上的原因是作为一个安全的哈希函数并不意味着该函数是一个适当的随机预言机仿真。简而言之,MAC 的安全性依赖于不一定从 hahs 函数获得的精确安全特性,即使哈希函数本身被认为是“安全的”,也就是“防碰撞”。自制 MAC 通常很弱(但不是明显很弱)。 HMAC 是一种结构,其中底层的散列函数被调用两次,这使得一些聪明的研究人员能够真正证明它作为 MAC 是安全的。
【解决方案2】:

如何测试字符串是否被正确解密?

“小前缀”的想法应该没问题;也是@CodeInChaos 的好主意。除此之外,以某种定义的格式(如serialize()json_encode())存储字符串并且无法恢复它(unserialize()json_decode())也将表明解密失败。

【讨论】:

  • 让我好奇的是,一个加密字符串上的两个不同密钥是否会产生两个完全不同但仍然有效的 JSON/序列化明文。
猜你喜欢
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多