【问题标题】:PHP mcrypt to PythonPHP mcrypt 到 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 函数。

标签: php python encryption mcrypt


【解决方案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 函数的功能,作为更大项目的一部分,以适应未来的发展。出于临时向后兼容的原因,我只是需要这个函数。
猜你喜欢
  • 2013-04-20
  • 2020-07-29
  • 2013-08-01
  • 2011-12-26
  • 2011-09-18
  • 2018-02-13
  • 2017-12-18
  • 2012-08-24
  • 2017-11-12
相关资源
最近更新 更多