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

时间:2011-02-22 19:00:25

标签: php encryption aes mcrypt

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

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

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

我花了一些时间思考。 如何测试字符串是否已正确解密?
如果我在首先加密它之前在原始字符串中添加了一个小前缀,然后在解密时删除了该前缀,该怎么办?如果未找到此前缀,则可以安全地说解密失败。

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

2 个答案:

答案 0 :(得分:2)

要测试数据完整性,您需要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模式。当使用--with-mhash选项编译时,PHP本身提供mhash()函数,该函数实现原始哈希和HMAC 。)

答案 1 :(得分:1)

  

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

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