可以';t从OpenSSL加密中解密PHP中的文件


Can't decrypt file in PHP from OpenSSL encryption

我正在命令行中使用OpenSSL加密JSON对象。然而,当我使用cURL发送它,然后尝试解密它时,我只得到不可打印的字节。这是我的流程:

在OpenSSL中加密

openssl aes-128-cbc -in object.json -out cipher.txt -pass pass:key.file -base64

cat object.json
{"payload":"这是一个测试"}

cat密钥.file
KWA6HNqb9UydXPbh72Vej82rT7NMVQZE

cat密码.txtU2FsdGVkX1/OOX/XSRXXOCmxfak5TXbag6ZSW6U95U+VLADuaH83zmP8hee017J

key.file正好是32个字节。我在服务器上有相同的密钥文件。我已经验证了它也是32字节。

使用cURL发送

curl --data "@cipher.txt" http://www.example.com/myscript.php

php脚本

$key = file_get_contents("key.file");
echo $key . "'n";
// get the ciphertext from the POST parameter   
$ciphertext = rawurlencode(file_get_contents("php://input"));
echo $ciphertext . "'n";
echo base64_decode(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC));

这是我得到的:

KWA6HNqb9UydXPbh72Vej82rT7NMVQZEU2FsdGVkX1%2FOOX%2FSSRXXOCmxfak5TXbag6ZSW6U95U%2BVLADuaH83zmP8hee017J
���G�/

我看不出我做错了什么。有人能告诉我我在哪里犯错误吗?谢谢

编辑我也尝试使用这个命令进行解密,但结果只得到一个空字符串:

echo base64_decode(openssl_decrypt($ciphertext, "AES-128-CBC", $key, OPENSSL_RAW_DATA));

-pass pass:key.file意味着您使用从密码key.file派生的密钥加密明文。如果要使用key.file的第一行,则需要使用-pass file:key.file。您可能不希望这样,因为密码不是密钥。PHP的mcrypt或openssl扩展没有提供直接使用从密码派生的相同密钥的方法。你可以在这里使用我的代码从密码中派生出相同的密钥和IV。

您需要使用OpenSSL命令行实用程序的-K选项来传入256位的"密钥"(密钥应该由任意字节组成,而不仅仅是可打印的字节)。密钥以十六进制编码的形式传递。如果这样做,那么还需要通过-iv选项传递128位IV。

由于您的"密钥"是256位(32字节)长,因此需要指定aes-256-cbc

其他问题:

OpenSSL默认使用PKCS#7填充(与PKCS#5填充同义),但mcrypt用0到15 0x00字节填充明文,这是不兼容的。在PHP中使用openssl扩展,它正确地使用PKCS#7填充。