PHP mcrypt 到 Python
Posted
技术标签:
【中文标题】PHP mcrypt 到 Python【英文标题】:PHP mcrypt to Python 【发布时间】:2017-10-14 19:30:55 【问题描述】:我正在尝试将 php 加密函数转换为 Python。为了示例方便,我们预先设置了iv和相关数据。
$salt = sha1('12345'.'654321');
encrypt('12345678', 'cutekittens12345', $salt);
function encrypt($decrypted, $password, $salt)
// Build a 256-bit $key which is a SHA256 hash of $salt and $password.
$key = hash('SHA256', $salt . $password, true);
$hexkey = hash('SHA256', $salt . $password, false);
// Build $iv and $iv_base64. We use a block size of 128 bits (AES compliant) and CBC mode. (Note: ECB mode is inadequate as IV is not used.)
#$iv = mcrypt_create_iv(16, MCRYPT_RAND);
$iv = "0000000000000000";
if (strlen($iv_base64 = rtrim(base64_encode($iv), '=')) != 22)
return false;
// Encrypt $decrypted and an MD5 of $decrypted using $key. MD5 is fine to use here because it's just to verify successful decryption.
$concatdecrypted = ($decrypted . md5($decrypted));
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $concatdecrypted, MCRYPT_MODE_CBC, $iv));
// We're done!
return $iv_base64 . $encrypted;
结果
$salt: 6ed52d21d5cc15e76e9879675f4bd0dd51593652
$hexkey: 879522bb98c1f5fb16acd6bf3454b0d4e313e8b71e0aa3cdf5cbf91158dfde71
$iv_base64: MDAwMDAwMDAwMDAwMDAwMA
$concatdecrypted: 1234567825d55ad283aa400af464c76d713c07ad
$encrypted: C3CWJPt2gtmg+id1ySmSazMvvWC7cgDpovJ/tDN0GeuVv9Pf/9+9ZSG+wjl6qD5h
我最干净的重新创建函数的尝试是here 并且:
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
import hashlib
charid = "654321"
apikey = "12345"
vcode = "12345678"
password = "cutekittens12345"
salt = hashlib.sha1((apikey + charid).encode('utf-8')).hexdigest()
key = hashlib.sha256(salt + password).digest()
iv = "0000000000000000"
concatkey = vcode + hashlib.md5(vcode).hexdigest()
AES.key_size=128
encryptor=AES.new(key=key,mode=AES.MODE_CBC,IV=iv)
encoded = encryptor.encrypt(concatkey_pad)
encoded = b64encode(encoded)
print 'Encrypted string:', encoded
我可以重新创建除了最终结果之外的所有内容。我尝试了 unhex 的组合,看看它是否与传递原始输入有关,但没有一个 $encrypted 结果匹配。
任何帮助将不胜感激。
【问题讨论】:
不要提供代码链接。相反,edit 你的问题包括代码。链接总是断开,如果断开,这个问题将失去所有价值。 很可能是填充问题。我会假设 Python 库应该使用 PKCS5Padding。 Mcrypt 没有。您应该修改您的 PHP 以使用 openssl_encrypt 函数。 【参考方案1】:我尝试了 M2Crypto、Crypto.Cipher 和 pyDes。在阅读'Lessons learned implementing AES in PHP using Mcrypt' 之后,我在用 ascii 0 填充字符串以绕过 16 的倍数问题后使用 Crypto.Cipher 取得了成功,并且编码字符串的前半部分与我的 php 函数匹配。
concatkey_pad = concatkey.ljust(48, '\0')
AES.key_size=128
encryptor=AES.new(key=key,mode=AES.MODE_CBC,IV=iv)
encoded = encryptor.encrypt(concatkey_pad)
encoded = b64encode(encoded)
print 'Encrypted string:', encoded
使用二进制 0 填充 concatkey 刚刚生成正确的编码值。
【讨论】:
@LukePark 虽然这可能是真的,但我的目标是重新创建已弃用的 PHP 函数的功能,作为更大项目的一部分,以适应未来的发展。出于临时向后兼容的原因,我只是需要这个函数。以上是关于PHP mcrypt 到 Python的主要内容,如果未能解决你的问题,请参考以下文章
更新到 php 5.6.2 时的 mcrypt 警告;不支持大小为 x 的密钥
在升级到 PHP 5.4.33 的 Centos VPS 上安装 mcrypt 扩展时出错