PHP7.4:OpenSSL AES-CFB加密不同于Python
我正在尝试使用PHP7.4复制一段python代码,该代码使用Pycryptodome进行AES-128-CFB加密。 为此,我使用了PHP的openssl_encrypt内置函数。 我尝试了几个配置参数和循环流化床模式,但我总是得到不同的结果。 我发现pycryptodomes CFB实现似乎使用了8位的段大小,这应该是PHP的openssl实现中的PHP7.4:OpenSSL AES-CFB加密不同于Python,python,php,encryption,aes,Python,Php,Encryption,Aes,我正在尝试使用PHP7.4复制一段python代码,该代码使用Pycryptodome进行AES-128-CFB加密。 为此,我使用了PHP的openssl_encrypt内置函数。 我尝试了几个配置参数和循环流化床模式,但我总是得到不同的结果。 我发现pycryptodomes CFB实现似乎使用了8位的段大小,这应该是PHP的openssl实现中的aes-128-cfb8模式 IV被故意固定为0,所以请忽略它不安全的事实 下面是我要复制的代码,后面是尝试用不同方法复制结果的PHP代码。 有些
aes-128-cfb8
模式
IV被故意固定为0,所以请忽略它不安全的事实
下面是我要复制的代码,后面是尝试用不同方法复制结果的PHP代码。
有些东西告诉我这与PHP的“字节处理”有关,因为python在字节字符串(由.encode('utf-8')
返回)和字符串之间进行区分。
最后,您可以看到两个代码的输出:
Python代码:
导入hashlib
从Crypto.Cipher导入AES
key='testKey'
IV='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
ENC_KEY=hashlib.md5(KEY.encode('utf-8')).hexdigest()
打印('key:'+key+'''))
打印('hashedKey:'+加密键)
obj=AES.new(ENC_KEY.encode(“utf8”)、AES.MODE_CFB、IV.encode(“utf8”))
测试数据=‘测试’
打印(“加密”+“测试”+”)
encData=obj.encrypt(测试数据编码(“utf8”))
打印('encData:'+encData.hex())
PHP代码:
函数encTest($testStr,$ENC_KEY)
{
$iv=hex2bin('00000000000000000000000000');
echo“aes-128-cfb8-1:”.bin2hex(openssl_加密($testStr,'aes-128-cfb8',$ENC_密钥,openssl_原始数据,$iv))。“\n”;
echo“aes-128-cfb1-1:”.bin2hex(openssl_加密($testStr,'aes-128-cfb1',$ENC_密钥,openssl_原始数据,$iv))。“\n”;
echo“aes-128-cfb-1:”.bin2hex(openssl_加密($testStr,'aes-128-cfb',$ENC_密钥,openssl_原始数据,$iv))。“\n”;
回音“\n”;
echo“aes-128-cfb8-2:”.bin2hex(openssl_加密($testStr,'aes-128-cfb8',$ENC_密钥,openssl_原始数据| openssl_零填充,$iv))。“\n”;
echo“aes-128-cfb1-2:”.bin2hex(openssl_加密($testStr,'aes-128-cfb1',$ENC_密钥,openssl_原始_数据| openssl_零填充,$iv))。“\n”;
echo“aes-128-cfb-2:”.bin2hex(openssl加密($testStr,'aes-128-cfb',$ENC_密钥,openssl_原始数据| openssl_零填充,$iv))。“\n”;
回音“\n”;
echo“aes-128-cfb8-3:”.bin2hex(openssl加密(utf8编码($testStr),'aes-128-cfb8',utf8编码($ENC密钥),openssl原始数据| openssl零填充,$iv))。“\n”;
echo“aes-128-cfb1-3:”.bin2hex(openssl加密(utf8编码($testStr),'aes-128-cfb1',utf8编码($ENC密钥),openssl原始数据| openssl零填充,$iv))。“\n”;
echo“aes-128-cfb-3:”.bin2hex(openssl加密(utf8编码($testStr),'aes-128-cfb',utf8编码($ENC密钥),openssl原始数据| openssl零填充,$iv))。“\n”;
回音“\n”;
echo“aes-128-cfb8-4:”.bin2hex(openssl_加密(utf8_编码($testStr),'aes-128-cfb8',utf8_编码($ENC_密钥),openssl_原始数据,$iv))。“\n”;
echo“aes-128-cfb1-4:”.bin2hex(openssl_加密(utf8_编码($testStr),'aes-128-cfb1',utf8_编码($ENC_密钥),openssl_原始数据,$iv))。“\n”;
echo“aes-128-cfb-4:”.bin2hex(openssl_加密(utf8_编码($testStr),'aes-128-cfb',utf8_编码($ENC_密钥),openssl_原始数据,$iv))。“\n”;
回音“\n”;
}
$key=“testKey”;
$ENC_KEY=hash('md5',utf8_encode($KEY));
回显“ENC_KEY:.$ENC_KEY.\n”;
$test=“test”;
回显“加密”.$test.\“\n”;
encTest($test,$ENC_-KEY);
Python输出(encData
应复制):
PHP输出:
key: "testKey"
hashedKey: 24afda34e3f74e54b61a8e4cbe921650
encrypting "test"
aes-128-cfb8-1: b0016a55
aes-128-cfb1-1: bac44c56
aes-128-cfb-1: b0f1c27a
aes-128-cfb8-2: b0016a55
aes-128-cfb1-2: bac44c56
aes-128-cfb-2: b0f1c27a
aes-128-cfb8-3: b0016a55
aes-128-cfb1-3: bac44c56
aes-128-cfb-3: b0f1c27a
aes-128-cfb8-4: b0016a55
aes-128-cfb1-4: bac44c56
aes-128-cfb-4: b0f1c27a
在PHP代码中(更准确地说,对于openssl\u encrypt
),明确指定了AES变量,例如,与当前使用AES-128-…
的情况相同,即PHP使用AES-128。过长的键将被截断,过短的键将填充0
值。由于PHP代码中的hash
方法将其结果返回为十六进制字符串,因此16字节MD5哈希由32个字符(32字节)表示,即在当前情况下,PHP使用密钥的前16个字节(AES-128)
Python代码中的hexdigest
方法也将结果作为十六进制字符串返回。但是,在Python代码中(更准确地说,对于PyCryptodome),AES变量由密钥大小指定,即Python代码使用完整的32字节密钥,因此使用AES-256
不同的密钥和AES变体是产生不同结果的主要原因。要解决此问题,两种代码中必须使用相同的密钥和AES变体:
- 选项1是在Python代码中也使用AES-128。这可以通过以下更改来实现:
然后输出的obj = AES.new(ENC_KEY[:16].encode("utf8"), AES.MODE_CFB, IV.encode("utf8"))
与b0016a55
的PHP代码结果一致aes-128-cfb8
- 选项2是在PHP代码中也使用AES-256。这可以通过将
替换为aes-128…
来实现,然后输出为aes-256…
aes-256-cfb8-1: 117c1974 aes-256-cfb1-1: 54096db1 aes-256-cfb-1 : 11bfdaa9
aes-128-cfb8
的输出117c1974
与Python代码的原始值匹配
CFB模式将分组密码更改为流密码。因此,
n
位在每个加密步骤中被加密,这被称为CFBn
。有关s.的确切细节
术语CFBn
(或CFBn
)也在PHP中使用,即CFB1
表示一位的加密,CFB8
表示8位(=一个字节)和整个块(16个字节)的CFB
。在Python中,每一步的位数是用指定的
也就是说,PHP中的..-cfb8
对应物在Python中是segment_size=8
,PHP中的..-cfb
对应物在Python中是segment_size=128
在下文中,假设两个代码中使用相同的密钥和相同的AES变体
由于默认值为segment\u size=8
,因此Python代码的结果与<
aes-256-cfb8-1: 117c1974
aes-256-cfb1-1: 54096db1
aes-256-cfb-1 : 11bfdaa9