問題描述
由于 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的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!