我尝试了crypto-js,但输出不正确,请查看我的代码并纠正我的错误



我的后端有一个simple_crypt函数,它运行正常,现在我想要的是为javascript制作一个类似的函数,它与php函数完全相同。因此,我研究并获得了CryptoJS库,与PHP库相比,我的"Key"one_answers"iv"值是正确的,但当我加密字符串时,输出完全不同。

这是我正在使用的PHP代码,我想将其转换为javascript。

<?php 
function simple_crypt( $string ) {
$secret_key = '1234567890';
$secret_iv = '0987654321';
$output = false;
$encrypt_method = "AES-256-CBC"; 
$key = hash( 'sha256', $secret_key );
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
echo "Key : ".$key."<br>";
echo "iv : ".$iv."<br>";
$output = openssl_encrypt( $string, $encrypt_method, $key, 0, $iv );
return $output;
}

$e =  simple_crypt("text");
echo $e;
echo "<br>";

?>

这是我的JS代码,我在其中遇到了问题,请看一看,并告诉我我在这个JS代码中错在哪里。

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js" integrity="sha512-nOQuvD9nKirvxDdvQ9OMqe2dgapbPB7vYAMrzJihw5m+aNcf0dX53m6YxM4LgA9u8e9eg9QX+/+mPu8kCNpV2A==" crossorigin="anonymous"></script>
<script type="text/javascript">
function simple_crypt(string) {
var secret_key, secret_iv, output, key, iv;
secret_key = '1234567890';
secret_iv = '0987654321';
output = false;

key = CryptoJS.SHA256(secret_key).toString();
iv = CryptoJS.SHA256(secret_iv).toString().substr(0, 16);
console.log("key",key);
console.log("iv",iv);

var encrypted = CryptoJS.AES.encrypt(string, key, {iv: iv});
return (encrypted.toString());
}
console.log(simple_crypt("text"));
</script>

以下是输出:
PHP:T4F65n4AVlmkkb5LLFhRIQ==
JS:U2FsdGVkX18HJGpPYZPm6crBcxA7TfbZZ9Sc/4qHGBk=

为了使两个代码产生相同的结果,NodeJS代码中的键和IV必须与PHP代码中的相同,并作为WordArrays传递。为此,必须对您生成的键和Ⅳ进行如下进一步处理:

key = CryptoJS.enc.Utf8.parse(key.substr(0, 32));
iv = CryptoJS.enc.Utf8.parse(iv);

在PHP代码中,SHA256散列作为十六进制字符串返回。使用十六进制编码,字节数加倍,即SHA256哈希是十六进制编码的64字节。PHP隐式地只考虑关于AES-256密钥的前32个字节,即忽略最后32个字节。在CryptoJS代码中,这必须发生显式(对于IV,这会发生,但对于密钥,这是缺失的(
通过使用UTF8编码器进行解析,密钥和IV被转换为WordArrays。如果密钥以字符串形式传递(如问题中发布的代码中所示(,则CryptoJS将该值解释为密码,并使用密钥派生函数来派生密钥和IV(这与PHP代码中的逻辑不兼容(。

经过上述更改,CryptoJS代码给出了与PHP代码相同的结果:

function simple_crypt(string) {
var secret_key, secret_iv, output, key, iv;
secret_key = '1234567890';
secret_iv = '0987654321';
output = false;
key = CryptoJS.SHA256(secret_key).toString();
iv = CryptoJS.SHA256(secret_iv).toString().substr(0, 16);
key = CryptoJS.enc.Utf8.parse(key.substr(0, 32));
iv = CryptoJS.enc.Utf8.parse(iv);
console.log("key",key.toString());
console.log("iv",iv.toString());
var encrypted = CryptoJS.AES.encrypt(string, key, {iv: iv});
return (encrypted.toString());
}
console.log(simple_crypt("text")); // T4F65n4AVlmkkb5LLFhRIQ==
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

请注意以下内容:

  • 使用SHA256从密码派生密钥是不安全的。为此,应该使用可靠的密钥推导函数,如PBKDF2
  • 出于安全原因,密钥/IV对只能应用一次。因此,IV通常是为每次加密随机生成的。IV不是秘密,通常与密文一起发送给收件人(通常是预先准备好的(。或者,IV可以使用KDF(与随机生成的盐组合(与密钥一起导出

相关内容

最新更新