我正在尝试将以下 shell 命令转换为 php,但我没有得到正确的结果
$key = 'my_key';
$cmd = "echo -n $plaintext| openssl enc -e -aes-256-cbc -a -k $key -md md5";
$exec = exec($cmd, $output, $status);
return $status == 0 ? $output[0] : null;
以上适用于 php7.4。我尝试过以下方法
$key = "my_key";
echo "key: $key\n";
//$key = password_hash($key, PASSWORD_BCRYPT, ['cost' => 12]);
//echo "key: $key\n";
$ciphertext = openssl_encrypt($plaintext, 'aes-256-cbc', $key, null, 'UqA8Z5ztUYnWhnUE');
echo "ciphertext: $ciphertext\n";
echo "merged: $key$ciphertext\n";
return $key . $ciphertext;
这不起作用。
key
由第 3 方提供
更新
我尝试过以下方法
创建密钥和 iv
# openssl enc -nosalt -aes-256-cbc -k hello-aes -P -md md5 *** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
key=C639A572E14D5075C526FDDD43E4ECF6B095EA17783D32EF3D2710AF9F359DD4
iv =D09A4D2C5DC39843FE075313A7EF2F4C
在cli上我可以使用密钥来加密和解密
加密
# echo -n [email protected] | openssl enc -e -aes-256-cbc -a -k C639A572E14D5075C526FDDD43E4ECF6B095EA17783D32EF3D2710AF9F359DD4 -md md5
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
U2FsdGVkX1+GpDPQ5uLeXlZL9CEgKaBDgDuwvf00m9U=
解密
# echo U2FsdGVkX1+GpDPQ5uLeXlZL9CEgKaBDgDuwvf00m9U= | openssl enc -d -aes-256-cbc -a -k C639A572E14D5075C526FDDD43E4ECF6B095EA17783D32EF3D2710AF9F359DD4 -md md5
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
[email protected]
在 PhP 中
我使用从 cli 创建的
key
和 iv
。 key
是提供给我的,我无法生成这个
function encryptAES256CBC(string $plaintext): string
{
$key = 'C639A572E14D5075C526FDDD43E4ECF6B095EA17783D32EF3D2710AF9F359DD4';
//echo "key hex2bin ". md5($key) . "\n\n";
$iv = hex2bin('D09A4D2C5DC39843FE075313A7EF2F4C');
echo "key: $key\n";
$cipher="aes-256-cbc";
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);//, null, 'UqA8Z5ztUYnWhnUE');
echo "ciphertext_raw: $ciphertext_raw\n";
echo "base64_encode: ".base64_encode($ciphertext_raw)."\n";
echo "base64_encode md5: ".md5(base64_encode($ciphertext_raw))."\n";
echo "md5: ".md5($ciphertext_raw)."\n";
return md5($ciphertext_raw);
return $key . $ciphertext_raw;
}
我尝试在 cli 上解码上述输出以检查其是否有效,但没有成功。我收到错误
bad magic number
输出
key: C639A572E14D5075C526FDDD43E4ECF6B095EA17783D32EF3D2710AF9F359DD4
ciphertext_raw: y▒▒yV▒ύ2▒G▒▒▒¤▒!▒▒▒%▒"ҋ~▒
base64_encode: B3n1+XlWtM+NMrlHue8R28KkmiG8tpUl/Iwi0ot+vg4=
base64_encode md5: f65b8e0ed4fc86d4b405d37a57bcd6e5
md5: 14e9f14ee94a2c34e52ad80e3f300d40
DECRYPT 14e9f14ee94a2c34e52ad80e3f300d40
[12:27:43] Destructor
root@0ea89b7ad9df:/# echo 14e9f14ee94a2c34e52ad80e3f300d40 | openssl enc -d -aes-256-cbc -a -k C639A572E14D5075C526FDDD43E4ECF6B095EA17783D32EF3D2710AF9F359DD4 -md md5
bad magic number
更新
我已经设法使解密工作,但加密不起作用
这就是我所拥有的
$passphrase = 'random';
$salt = openssl_random_pseudo_bytes(8);
$keyData = self::evpBytesToKey($salt, $passphrase);
$key = substr($keyData, 0, 32);
$iv = substr($keyData, 32, 16);
$method = 'AES-256-CBC';
$ciphertext_raw = openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv);
echo "ciphertext_raw: $ciphertext_raw\n";
echo "base64_encode: ".base64_encode($ciphertext_raw)."\n";
echo "base64_encode md5: ".md5(base64_encode($ciphertext_raw))."\n";
echo "md5: ".md5($ciphertext_raw)."\n";
echo "merged: ".base64_encode($iv.$ciphertext_raw)."\n";
return md5($ciphertext_raw);
return base64_encode("Salted__" . $salt . $ciphertext_raw);
以下代码是一个完整的运行示例,使用 @Topaco 评论的“EVP_BytesToKey”密钥派生。
请注意,这种密钥派生是不安全,因为它使用损坏的MD5算法且迭代计数仅为1。请仅将代码用于迁移目的,谢谢。
这是一个可能的输出[因为存在随机元素,您的输出会有所不同]:
AES CBC 256 String encryption with passphrase
# # # SECURITY WARNING: This code is provided for achieve # # #
# # # compatibility between different programming languages. # # #
# # # It is not necessarily fully secure. # # #
# # # Its security depends on the complexity and length # # #
# # # of the password, because of only one iteration and # # #
# # # the use of MD5. # # #
# # # DO NOT USE THIS CODE IN PRODUCTION # # #
passphrase: my secret passphrase
* * * Encryption * * *
ciphertext: U2FsdGVkX1/+hqfCdNaZ36kZzPzwvFXkr4nEySMEgdVdPnPrGUj2Gi1t2pspAH2WHVEVgKHKWfR2Gc0sKnTlLg==
output is (Base64) ciphertext
* * * Decryption * * *
passphrase: my secret passphrase
ciphertext (Base64): U2FsdGVkX19rV+JOoeF72K54jlyJ47tNEsMjih7gDnFUysZFaw+WnYTB5L/hc2+rssFj1hXw3N8kkikHwClB2w==
input is (Base64) ciphertext
plaintext: The quick brown fox jumps over the lazy dog
代码:
<?php
// source: https://github.com/blocktrail/cryptojs-aes-php/blob/master/src/CryptoJSAES.php
// author: BlockTrail
function aesCbcPassphraseEncryptToBase64($passphrase, $data, $salt = null) {
$salt = $salt ?: openssl_random_pseudo_bytes(8);
list($key, $iv) = evpkdf($passphrase, $salt);
$ct = openssl_encrypt($data, 'aes-256-cbc', $key, true, $iv);
return encode($ct, $salt);
}
function aesCbcPassphraseDecryptFromBase64($passphrase, $base64) {
list($ct, $salt) = decode($base64);
list($key, $iv) = evpkdf($passphrase, $salt);
$data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv);
return $data;
}
function evpkdf($passphrase, $salt) {
$salted = '';
$dx = '';
while (strlen($salted) < 48) {
$dx = md5($dx . $passphrase . $salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv = substr($salted, 32, 16);
return [$key, $iv];
}
function decode($base64) {
$data = base64_decode($base64);
if (substr($data, 0, 8) !== "Salted__") {
return "";
}
$salt = substr($data, 8, 8);
$ct = substr($data, 16);
return [$ct, $salt];
}
function encode($ct, $salt) {
return base64_encode("Salted__" . $salt . $ct);
}
echo 'AES CBC 256 String encryption with passphrase' . PHP_EOL;
echo PHP_EOL . '# # # SECURITY WARNING: This code is provided for achieve # # #' . PHP_EOL;
echo '# # # compatibility between different programming languages. # # #' . PHP_EOL;
echo '# # # It is not necessarily fully secure. # # #' . PHP_EOL;
echo '# # # Its security depends on the complexity and length # # #' . PHP_EOL;
echo '# # # of the password, because of only one iteration and # # #' . PHP_EOL;
echo '# # # the use of MD5. # # #' . PHP_EOL;
echo '# # # DO NOT USE THIS CODE IN PRODUCTION # # #' . PHP_EOL;
$plaintext = 'The quick brown fox jumps over the lazy dog';
$passphrase = 'my secret passphrase';
echo PHP_EOL . 'passphrase: ' . $passphrase . PHP_EOL;
echo PHP_EOL . '* * * Encryption * * *' . PHP_EOL;
$ciphertextBase64 = aesCbcPassphraseEncryptToBase64($passphrase, $plaintext);
echo 'ciphertext (Base64): ' . $ciphertextBase64 . PHP_EOL;
echo 'output is (Base64) ciphertext' . PHP_EOL;
echo PHP_EOL . '* * * Decryption * * *' . PHP_EOL;
$decryptionPassphrase = $passphrase;
$ciphertextDecryptionBase64 = $ciphertextBase64;
echo 'decryptionPassphrase: ' . $decryptionPassphrase . PHP_EOL;
echo 'ciphertext (Base64): ' . $ciphertextDecryptionBase64 . PHP_EOL;
echo 'input is (Base64) ciphertext' . PHP_EOL;
$decryptedtext = aesCbcPassphraseDecryptFromBase64($decryptionPassphrase, $ciphertextDecryptionBase64);
echo 'plaintext: ' . $decryptedtext . PHP_EOL;
?>