问题描述
由于 mcrypt 已过时,我的任务是升级当前代码以使用 openssl.听起来很简单,但是……经过几天的尝试和失败后,我感觉自己快要疯了.
Since mcrypt is considered obsolete, my task is upgrading the current code to use openssl. Sounds simple, but ... after a few days of try and failure I feel like going insane.
我要问你的问题是:有什么办法可以用以前用 mcrypt 加密的 openssl 数据解密?我已经阅读了很多关于这个问题的帖子,他们中的大多数人都说在运行 mcrypt 之前需要手动填充数据.问题是 mcrypt 编辑的数据已经加密(使用 mcrypt 提供的自动空填充)并驻留在数据库中,因此不可能和/或不希望对其进行修改.
My question to you is: Is there any way you can decrypt with openssl data previously encrypted with mcrypt? I've read so many posts on this matter and most of them say that a previous manual padding of the data was/is necessary before running mcrypt on it. The issue is that the mcrypt-ed data is already encrypted (with the automatic null padding mcrypt provides) and resides in a database, so modification of that is not possible and/or desired.
提及:
- 使用的算法是带有 32 字节密钥的 rijndael-128 cbc(所以我将 aes-256-cbc 用于 openssl).
- 我正在为 php (php-crypto) 使用 openssl 包装器.
- 通过简单地剥离非字母数字的结尾解码字符,我设法使逆运算起作用(使用 mcrypt 解码 openssl).
- 在 mcrypt-ing 之前手动填充数据,然后使用 openssl 解密它就像一个魅力,但这不是这里的问题.
一些代码片段:
// Simple mcrypt encrypt, decrypt with php-crypto example
// This doesn't work and produces a "Finalizing of cipher failed" error
$data = "This is a text";
$strMcryptData=mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);
$algorithm = 'aes-256-cbc';
$cipher = new Cipher($algorithm);
$sim_text = $cipher->decrypt($strMcryptData, $key, $iv);
// Simple mcrypt encrypt with padding, decrypt with php-crypto
// Works and produces the correct text on decryption
$pad = $blocksize - (strlen($data) % $blocksize);
$text = $data;
$text .= str_repeat(chr($pad), $pad);
$strPaddedData=mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
$sim_text = $cipher->decrypt($strPaddedData, $key, $iv);
推荐答案
如果你在 mcrypt 中加密而不手动添加 PKCS7,mcrypt 会很乐意用 NUL
字节填充你的明文.
If you encrypt in mcrypt without adding PKCS7 manually, mcrypt will happily pad your plaintext with NUL
bytes.
每当使用 aes-X-cbc
时,OpenSSL 都会为您做 PKCS7 填充.这样做的不幸后果是,如果您有 AES-CBC(NULL_PADDED(plaintext))
并尝试解密它,openssl_decrypt
将尝试删除填充并失败.
OpenSSL will do PKCS7 padding for you whenever using aes-X-cbc
. The unfortunate consequence of this is that if you have AES-CBC(NULL_PADDED(plaintext))
and try to decrypt it, openssl_decrypt
will attempt to remove the padding and fail.
比较 http://3v4l.org/bdQe9 与 http://3v4l.org/jr68f 和 http://3v4l.org/K6ZEU
OpenSSL 扩展目前没有为您提供此字符串未填充,请不要为我去除填充"然后自行删除 NUL
字节的方法.您必须使用 PKCS7 填充加密才能成功解密.
The OpenSSL extension does not currently offer you a way to say "This string is not padded, please don't strip the padding for me" and then remove the NUL
bytes on your own. You must encrypt with PKCS7 padding in order for decryption to succeed.
虽然这是 OpenSSL 的一个限制,但需要强调的是,您遇到它的唯一原因是因为 mcrypt 很糟糕.
Although this is a limitation of OpenSSL, it bears emphasizing that the only reason you're running into it is because mcrypt is terrible.
这篇关于使用 openssl 解密 mcrypt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!