gpt4 book ai didi

javascript - JavaScript 中的加密和 PHP 中的解密

转载 作者:行者123 更新时间:2023-11-28 05:50:42 27 4
gpt4 key购买 nike

我正在 JavaScript 中加密我的用户密码,如下所示:

 var encryptedPassword = CryptoJS.AES.encrypt(password, "Secret Passphrase");

它工作正常,但现在我尝试在服务器端用 PHP 解密,如下所示:

 $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$decryptPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, "Secret Passphrase", base64_decode($password), MCRYPT_MODE_CBC, $iv);

它根本不起作用,解密后的密码字符串看起来很奇怪:

 string(64) ">�OX2MS��댗v�<$�ʕ��i�̄��_��P���\�կ=�_6(�m����,4WT7��a"

下面是我的 JavaScript 代码在有用的注释之后的当前状态:

    var encryptedPassword = CryptoJS.AES.encrypt(password, "Secret Passphrase");
var ivHex = encryptedPassword.iv.toString();
var ivSize = encryptedPassword.algorithm.ivSize; // same as blockSize
var keySize = encryptedPassword.algorithm.keySize;
var keyHex = encryptedPassword.key.toString();
var saltHex = encryptedPassword.salt.toString(); // must be sent
var openSslFormattedCipherTextString = encryptedPassword.toString(); // not used
var cipherTextHex = encryptedPassword.ciphertext.toString(); // must be sent

我正在将 saltHex 和 CipherTextHex 发送到 PHP 服务器,并且我正在使用 mcrypt_decrypt(),如下所示:

 $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), $saltHex);
$decryptPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, "Secret Passphrase", base64_decode($cipherTextHex), MCRYPT_MODE_CBC, $iv);

它仍然无法使用此更新的代码。

有人可以帮助我使用 mcrypt_decrypt() PHP 函数正确解密简单的 AES 加密方法吗?我确定我的 mcrypt_decrypt() 方法中的密码、mcrypt 模式和 IV 参数有问题。如果您知道的话谢谢。

最佳答案

问题在于,在 CryptoJS 代码中,使用密码来导出用于 AES 加密的 key 和 IV,但 mcrypt 仅使用 key 进行加密/解密。该信息需要传递给 php.ini。由于您不想传输密码,因此必须在 php 中以相同的方式导出 key 和 IV。

以下代码从密码和盐中派生出 key 和 IV。它是根据我的答案 here 中的代码建模的(了解更多信息)。

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)
);
}

盐是在CryptoJS加密过程中生成的,需要与密文一起发送到php。在调用 evpKDF 之前,必须将盐从十六进制转换为二进制字符串。

$keyAndIV = evpKDF("Secret Passphrase", hex2bin($saltHex));
$decryptPassword = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
$keyAndIV["key"],
hex2bin($cipherTextHex),
MCRYPT_MODE_CBC,
$keyAndIV["iv"]);
<小时/>

如果仅将encryptedPassword.toString()发送到服务器,则需要在使用前将salt和实际密文分开。该格式是专有的 OpenSSL 兼容格式,前 8 个字节是“Salted__”,接下来的 8 个字节是随机盐,其余是实际的密文。所有内容都经过 Base64 编码。

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 = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
$keyAndIV["key"],
substr($ciphertext, 16),
MCRYPT_MODE_CBC,
$keyAndIV["iv"]);

// unpad (PKCS#7)
return substr($decryptPassword, 0, strlen($decryptPassword) - ord($decryptPassword[strlen($decryptPassword)-1]));
}

使用 OpenSSL 扩展而不是 Mcrypt 也可以实现同样的效果:

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;
}

关于javascript - JavaScript 中的加密和 PHP 中的解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38103587/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com