加密:测试字符串是否正确解密?
这是一个理论,不仅适用于 PHP,而且可能适用于更多语言。
假设我使用 mcrypt
库和 AES-256
密码对字符串进行加密。加密后的字符串现在看起来类似于 àªÆ{”ò(ü´îÚÜÇW¹ËŸK̿L'rø?ª¶!JF£º+Œ'Ú'‚
。
如果加密密钥在解密和加密的事件,解密的结果显然毫无价值。
由于加密的字符串至少对我来说包含随机字符,因此对其进行某种测试以确保它处于加密/解密状态并不容易。
我花了一些时间思考。 如何测试字符串是否已正确解密?
如果我在首先加密原始字符串之前在原始字符串中附加一个小前缀,然后在解密时删除该前缀会怎么样?如果没有找到这个前缀,就可以肯定地说解密失败。
这是处理这个问题的适当方法吗?
Here's a theoretical one that not only applies to PHP, but probably to more languages.
Let's say that I encrypt a string with the mcrypt
library using and the AES-256
cipher. The string, encrypted, would now look similar to þøÆ{”ò(ü´îÚÜÇW¹ËŸK¯L‘rø?ª¶!JF£º+Œ’Ú'‚
.
If the encryption key would change between the events of decryption and encryption, the result of the decryption would obviously be worthless.
Since an encrypted string contains, at least to me, random chars, It wouldn't be easy to run some sort of test on it to ensure that it is in encrypted/decrypted state.
I've spent some time thinking. How can I test that a string has been properly decrypted?
What if I appended a small prefix to the original string before encrypting it in the first place, and then removed this prefix upon decryption. If this prefix wasn't found, it would be safe to say that the decryption has failed.
Would this be an appropriate way to handle this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要测试数据完整性,您需要消息身份验证代码 (MAC)。
有一些独立的 MAC 算法,它们看起来像带有密钥的哈希函数。非常标准的 MAC 算法是 HMAC (使用哈希函数)。
由于您还对数据进行加密,因此您将需要使用内置 MAC 的加密模式;有一些这样的模式,例如 GCM 或 EAX。这些模式适用于分组密码,通常是 AES。
在加密前给数据添加已知的前缀或后缀就是自制的MAC。 MAC 很微妙且容易出错。例如,如果您添加 CRC32,然后使用流密码(或 CTR 模式下的分组密码)进行加密,那么您将复制 WEP 的七大罪过(特别参见第 4 节,关于 CRC32-as-MAC 问题)。基本上你的完整性检查不再能抵抗主动攻击;您只是检测到无害的错误,例如使用了错误的密钥。
(不幸的是,MCrypt 似乎不支持任何组合加密/MAC 模式。PHP 本身在使用
--with-mhash
选项编译时,提供了mhash()
实现原始哈希和 HMAC 的函数。)To test data integrity you want a Message Authentication Code (MAC).
There are a few stand-alone MAC algorithms, which look like a hash function with a key. The very standard MAC algorithm is HMAC (which uses a hash function).
Since you also encrypt the data, you will want to use an encryption mode with a builtin MAC; there are a few such modes, such as GCM or EAX. Those modes apply to a block cipher, usually the AES.
Adding a known prefix or suffix to the data before encryption is a homemade MAC. MACs are subtle and error prone. For instance, if you add a CRC32 and then encrypt with a stream cipher (or a block cipher in CTR mode), then you are reproducing one of the seven capital sins of WEP (see section 4 in particular, for the CRC32-as-MAC issue). Basically your integrity check is no longer resistant to active attacks; you are only detecting innocent mistakes, such as using the wrong key.
(Unfortunately, it seems that MCrypt does not support any combined encryption/MAC mode. PHP itself, when compiled with the
--with-mhash
option, provides themhash()
function which implements both raw hashing, and HMAC.)“小前缀”的想法应该没问题;也是 @CodeInChaos 的好主意。除此之外,以某种定义的格式存储字符串(例如
serialize()
或json_encode()
)并且无法恢复它(unserialize()
>,json_decode()
) 也表明解密已损坏。The "small prefix" idea should be fine; also the excellent idea by @CodeInChaos. Other than that, storing the string in some defined format (like
serialize()
orjson_encode()
) and failing to restore it (unserialize()
,json_decode()
) would be indication of a broken decryption as well.