使用 PHP 的密钥解密 Crypto-js 加密文本
Decrypt Crypto-js encrypted text with key with PHP
我正在使用 Crypto-js 使用密钥加密密码并将其发送到服务器。我想使用 PHP 在服务器中解密它。如何做到这一点?
JS:
let encKey = "Secret Passphrase";
let text = "123";
let iv = CryptoJS.enc.Hex.parse("FgLFXEr1MZl2mEnk");
var encryptedText = CryptoJS.AES.encrypt(text, encKey, { iv: iv }).toString();
加密文本:
U2FsdGVkX1+EaW3J1GE1k/EU5h6C+nxBH364Xhez+b0=
PHP:
<?php
$strg = "U2FsdGVkX1+EaW3J1GE1k/EU5h6C+nxBH364Xhez+b0=";
$encryptedstrings = base64_decode($strg);
$encryptionMethod = 'aes-256-cbc';
$key = "Secret Passphrase";
$iv = "FgLFXEr1MZl2mEnk";
$rawText = openssl_decrypt($encryptedstrings, $encryptionMethod, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING , $iv);
var_dump($rawText);
结果:
string(32) "����>���s��ȡ�V?E��M���I"
我在这里得到奇怪的结果。
以下解决方案不是我的,而是来自@Artjom B.,所以所有的功劳都归于他。您将在此处找到来源:.
针对您的问题:您 运行 使用 密码 而不是密钥的 CryptoJs 加密。根据文档 (https://cryptojs.gitbook.io/docs/#the-cipher-algorithms) 部分密码算法,(内部 AES)密钥是从具有 过时且不安全的 函数的密码派生的,不应再使用。
Artjom B. 能够在 PHP 上提供此密钥派生。作为旁注:没有必要提出一个
初始化向量 (IV) 到加密函数,因为 IV 也是从密码短语派生的,所以我将其保留
在下面的代码中。
这是PHP端的结果:
solution for
string(3) "123"
decryptedtext: 123
这是代码,请注意警告:
提供此代码是为了实现不同编程语言之间的兼容性。它不一定是完全安全的。它的安全性取决于密码的复杂性和长度,因为只有一次迭代和使用 MD5。我建议使用至少 20 个字符的密码,最好是随机生成的字母数字字符。
<?php
/*
source: author: Artjom B.
Security notice: 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. I would recommend to use at least a 20 character password
with alphanumeric characters which is ideally randomly generated.
*/
function evpKDF($password, $salt, $keySize = 8, $ivSize = 4, $iterations = 1, $hashAlgorithm = "md5") {
$targetKeySize = $keySize + $ivSize;
$derivedBytes = "";
$numberOfDerivedWords = 0;
$block = NULL;
$hasher = hash_init($hashAlgorithm);
while ($numberOfDerivedWords < $targetKeySize) {
if ($block != NULL) {
hash_update($hasher, $block);
}
hash_update($hasher, $password);
hash_update($hasher, $salt);
$block = hash_final($hasher, TRUE);
$hasher = hash_init($hashAlgorithm);
// Iterations
for ($i = 1; $i < $iterations; $i++) {
hash_update($hasher, $block);
$block = hash_final($hasher, TRUE);
$hasher = hash_init($hashAlgorithm);
}
$derivedBytes .= substr($block, 0, min(strlen($block), ($targetKeySize - $numberOfDerivedWords) * 4));
$numberOfDerivedWords += strlen($block)/4;
}
return array(
"key" => substr($derivedBytes, 0, $keySize * 4),
"iv" => substr($derivedBytes, $keySize * 4, $ivSize * 4)
);
}
function decrypt($ciphertext, $password) {
$ciphertext = base64_decode($ciphertext);
if (substr($ciphertext, 0, 8) != "Salted__") {
return false;
}
$salt = substr($ciphertext, 8, 8);
$keyAndIV = evpKDF($password, $salt);
$decryptPassword = openssl_decrypt(
substr($ciphertext, 16),
"aes-256-cbc",
$keyAndIV["key"],
OPENSSL_RAW_DATA, // base64 was already decoded
$keyAndIV["iv"]);
return $decryptPassword;
}
echo 'solution for ' . PHP_EOL;
$key = "Secret Passphrase";
$strg = "U2FsdGVkX1+EaW3J1GE1k/EU5h6C+nxBH364Xhez+b0=";
$rawText = decrypt($strg, $key);
var_dump($rawText);
echo 'decryptedtext: ' . $rawText . PHP_EOL;
?>
我正在使用 Crypto-js 使用密钥加密密码并将其发送到服务器。我想使用 PHP 在服务器中解密它。如何做到这一点?
JS:
let encKey = "Secret Passphrase";
let text = "123";
let iv = CryptoJS.enc.Hex.parse("FgLFXEr1MZl2mEnk");
var encryptedText = CryptoJS.AES.encrypt(text, encKey, { iv: iv }).toString();
加密文本:
U2FsdGVkX1+EaW3J1GE1k/EU5h6C+nxBH364Xhez+b0=
PHP:
<?php
$strg = "U2FsdGVkX1+EaW3J1GE1k/EU5h6C+nxBH364Xhez+b0=";
$encryptedstrings = base64_decode($strg);
$encryptionMethod = 'aes-256-cbc';
$key = "Secret Passphrase";
$iv = "FgLFXEr1MZl2mEnk";
$rawText = openssl_decrypt($encryptedstrings, $encryptionMethod, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING , $iv);
var_dump($rawText);
结果:
string(32) "����>���s��ȡ�V?E��M���I"
我在这里得到奇怪的结果。
以下解决方案不是我的,而是来自@Artjom B.,所以所有的功劳都归于他。您将在此处找到来源:.
针对您的问题:您 运行 使用 密码 而不是密钥的 CryptoJs 加密。根据文档 (https://cryptojs.gitbook.io/docs/#the-cipher-algorithms) 部分密码算法,(内部 AES)密钥是从具有 过时且不安全的 函数的密码派生的,不应再使用。
Artjom B. 能够在 PHP 上提供此密钥派生。作为旁注:没有必要提出一个 初始化向量 (IV) 到加密函数,因为 IV 也是从密码短语派生的,所以我将其保留 在下面的代码中。
这是PHP端的结果:
solution for
string(3) "123"
decryptedtext: 123
这是代码,请注意警告: 提供此代码是为了实现不同编程语言之间的兼容性。它不一定是完全安全的。它的安全性取决于密码的复杂性和长度,因为只有一次迭代和使用 MD5。我建议使用至少 20 个字符的密码,最好是随机生成的字母数字字符。
<?php
/*
source: author: Artjom B.
Security notice: 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. I would recommend to use at least a 20 character password
with alphanumeric characters which is ideally randomly generated.
*/
function evpKDF($password, $salt, $keySize = 8, $ivSize = 4, $iterations = 1, $hashAlgorithm = "md5") {
$targetKeySize = $keySize + $ivSize;
$derivedBytes = "";
$numberOfDerivedWords = 0;
$block = NULL;
$hasher = hash_init($hashAlgorithm);
while ($numberOfDerivedWords < $targetKeySize) {
if ($block != NULL) {
hash_update($hasher, $block);
}
hash_update($hasher, $password);
hash_update($hasher, $salt);
$block = hash_final($hasher, TRUE);
$hasher = hash_init($hashAlgorithm);
// Iterations
for ($i = 1; $i < $iterations; $i++) {
hash_update($hasher, $block);
$block = hash_final($hasher, TRUE);
$hasher = hash_init($hashAlgorithm);
}
$derivedBytes .= substr($block, 0, min(strlen($block), ($targetKeySize - $numberOfDerivedWords) * 4));
$numberOfDerivedWords += strlen($block)/4;
}
return array(
"key" => substr($derivedBytes, 0, $keySize * 4),
"iv" => substr($derivedBytes, $keySize * 4, $ivSize * 4)
);
}
function decrypt($ciphertext, $password) {
$ciphertext = base64_decode($ciphertext);
if (substr($ciphertext, 0, 8) != "Salted__") {
return false;
}
$salt = substr($ciphertext, 8, 8);
$keyAndIV = evpKDF($password, $salt);
$decryptPassword = openssl_decrypt(
substr($ciphertext, 16),
"aes-256-cbc",
$keyAndIV["key"],
OPENSSL_RAW_DATA, // base64 was already decoded
$keyAndIV["iv"]);
return $decryptPassword;
}
echo 'solution for ' . PHP_EOL;
$key = "Secret Passphrase";
$strg = "U2FsdGVkX1+EaW3J1GE1k/EU5h6C+nxBH364Xhez+b0=";
$rawText = decrypt($strg, $key);
var_dump($rawText);
echo 'decryptedtext: ' . $rawText . PHP_EOL;
?>