在 PHP 中使用 AES CBC 解密简单脚本 - 从 Python 迁移

Decrypting simple script using AES CBC in PHP - migrating from Python

目前此代码在 Python 中运行,没有问题:

#!/usr/bin/python   
print('Content-type: text/html\r\n\r')


#! /usr/bin/env python -2
from binascii import hexlify, unhexlify
from Crypto.Cipher import AES
#
# PICCData decryption
# PICCData = AES-128_DECRYPT(KSDMMetaRead; PICCDataTag[||UID] [||SDMReadCtr]||RandomPadding)
IV = 16 * '\x00'
key = 16 * '\x00' # FileAR.SDMMetaRead Key
# Enc_PICC_Data = '\xEF\x96\x3F\xF7\x82\x86\x58\xA5\x99\xF3\x04\x15\x10\x67\x1E\x88'
Enc_PICC_Data = 'EF963FF7828658A599F3041510671E88'
myaes = AES.new(key, AES.MODE_CBC, IV=IV)
PICCData = myaes.decrypt(unhexlify(Enc_PICC_Data))

print (hexlify(PICCData))

响应是:

b'c704de5f1eacc0403d0000da5cf60941'

我无法从根本上迁移此代码。我尝试了以下变体,无论我做什么,都没有 return 任何响应。我可能正在做一些非常愚蠢的事情:

$e = 'EF963FF7828658A599F3041510671E88';
$key = '00000000000000000000000000000000';
$iv = '00000000000000000000000000000000';

$output = openssl_decrypt($e, 'AES-128-CBC', $key, 0, $iv);
echo $output;

非常感谢,感谢您的帮助。

您的代码有 3 个问题。

首先:您正在使用 hexstring 值形式的输入值 - 它们必须使用 hex2bin.

转换为二进制数据

其次:您的 PHP 脚本使用了 随机填充 因此它添加了一些数据以使每次运行时的输出看起来都不同。对于解密,只有前 16 个字节(32 个十六进制字符)将被使用(那些在你的 $e 变量中)你必须强制 OpenSSL 拒绝任何填充 - 这就是选项“OPENSSL_ZERO_PADDING”的好处。

第三:另一个选项“OPENSSL_RAW_DATA”强制 OpenSSL 获取原始数据而不是 base64 编码数据。

将所有三个部分放在您收到预期明文的代码中(此处为十六进制字符串):c704de5f1eacc0403d0000da5cf60941

控制台:

output: ��_��@=  �\�    A
output in hex: c704de5f1eacc0403d0000da5cf60941

安全警告:以下代码是不安全的(例如static key & iv)并且没有异常处理!

代码:

<?php
$e = hex2bin('EF963FF7828658A599F3041510671E88');
$key = hex2bin('00000000000000000000000000000000');
$iv = hex2bin('00000000000000000000000000000000');

$output = openssl_decrypt($e, 'AES-128-CBC', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
echo 'output: ' . $output . PHP_EOL;
echo 'output in hex: ' . bin2hex($output);
?>