Php 加密:测试字符串是否正确解密?

Php 加密:测试字符串是否正确解密?,php,encryption,aes,mcrypt,Php,Encryption,Aes,Mcrypt,这是一个不仅适用于PHP,而且可能适用于更多语言的理论 假设我使用mcrypt库和AES-256密码对字符串进行加密。经过加密的字符串现在看起来类似于 如果加密密钥在解密和加密事件之间发生变化,解密结果显然毫无价值。 因为一个加密字符串至少对我来说包含随机字符,所以要对它运行某种测试以确保它处于加密/解密状态并不容易 我花了一些时间思考。如何测试字符串是否已正确解密? 如果我在对原始字符串进行加密之前在其上附加一个小前缀,然后在解密时删除该前缀会怎么样?如果找不到该前缀,可以肯定地说解密失败了

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

假设我使用
mcrypt
库和
AES-256
密码对字符串进行加密。经过加密的字符串现在看起来类似于

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

我花了一些时间思考。如何测试字符串是否已正确解密?
如果我在对原始字符串进行加密之前在其上附加一个小前缀,然后在解密时删除该前缀会怎么样?如果找不到该前缀,可以肯定地说解密失败了

这是一个合适的处理方式吗

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


“小前缀”的想法应该很好;这也是@CodeInChaos的一个很好的想法。除此之外,以某种定义的格式存储字符串(如
serialize()
json\u encode()
)并且无法恢复它(
unserialize()
json\u decode()
)也可能是解密失败的迹象。

要测试数据完整性,您需要一个(MAC)

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

由于您还对数据进行加密,因此您将希望使用内置MAC的加密模式;有几种这样的模式,如或。这些模式适用于分组密码,通常为

在加密之前向数据添加已知前缀或后缀是一种自制的MAC。MAC非常微妙且容易出错。例如,如果您添加CRC32,然后使用流密码(或CTR模式下的分组密码)进行加密,则您正在复制其中一个(关于CRC32作为MAC的问题,请特别参阅第4节)。基本上,您的完整性检查不再抵抗主动攻击;您只检测无辜的错误,例如使用错误的密钥


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

您可以包含哈希(例如sha-1),而不是一个简单的前缀。这样你就可以得到完整性检查作为奖励。@Code这是一个好主意。哈希后面必须有一个定义的字符来标记边界。关于你的方法,如果你能找到一个字符串$a,那么对于每个可能的字符串$b,$a的编码就永远不会以$a.W开头,这是安全的为什么需要定义的字符?典型的散列具有恒定的大小。例如,sha-1散列只有20个字节。@CodeInChaos如果加密字符串的大小相当大,甚至是一个文件/文档,这是一个好主意。我怀疑在小字符串上实现是否是一个好主意,尽管我对两个dif的可能性感到好奇一个加密字符串上的不同键产生两个完全不同但仍然有效的JSON/序列化明文。嗨,Thomas。感谢您的广泛回答。我需要一些时间来消化它!关于PHP中的
mhash()
函数,它已被
hash()
替换,在本例中(?)
hash_hmac
只是一个简单的例子:为什么MAC的微妙和容易出错,正如你所说?@Industrial:概念上的原因是,作为一个安全的哈希函数并不意味着该函数是一个适当的随机oracle模拟。简单地说,MAC的安全性依赖于精确的安全特性,而你不一定从中获得这些特性m a hahs函数,即使哈希函数本身被认为是“安全的”,也就是“抗碰撞的”。自制的MAC通常很弱(但不是明显很弱)。HMAC是一种结构,底层哈希函数被调用两次,这使得一些聪明的研究人员能够实际证明它与MAC一样安全。