前端JS使用CryptoJS对称加密时,PHP后端对应解密失败
先粘贴一段JS加密步骤的代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<script>
var key = '56d4wa56d456sa4d5s6a4ds56a4d5s6a';
var iv = '5412512512';
function encrypt(text,k,i){
var key = CryptoJS.enc.Utf8.parse(CryptoJS.MD5(k));
var iv = CryptoJS.enc.Utf8.parse(CryptoJS.MD5(i).toString().substr(8, 16));
var encrypted = CryptoJS.AES.encrypt(text, key, {
iv: iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
console.log(encrypt('123456',key,iv)); //输出 cJ1b6TqsnoNFEkSuD3z5RQ==
</script>
这是前端的加密,key和iv是其他方法动态获取的
用户提交部分数据会通过这个方法加密,后端PHP解密后存储
通过网上知识和gpt问答得出的php解密方法
$key = '56d4wa56d456sa4d5s6a4ds56a4d5s6a';
$iv = '5412512512';
$encryptedText = 'cJ1b6TqsnoNFEkSuD3z5RQ==';
$decryptedText = dencryptWithOpenssl($encryptedText, $key, $iv);
echo $decryptedText; // 输出解密后的文本
function dencryptWithOpenssl($data,$key,$iv)
{
$data = base64_decode($data);
$key = md5($key);
$iv = substr(md5($iv), 8, 16); // 使用MD5哈希的中间16个字符作为IV
$decryptedData= openssl_decrypt($data, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);
if ($decryptedData === false) {
return "Decryption failed: " . openssl_error_string();
}else{
return $decryptedData;
}
}
实际php解密对应cJ1b6TqsnoNFEkSuD3z5RQ==返回false
困扰了很久,通过前端后端调试打印key和iv都是一致的的,但是后端一解密就失败
最早通过固定key和iv为固定16长度字符串进行测试,这种情况下前端加密后端解密时正常的,但是一旦key和iv是动态时,前端通过CryptoJS.enc.Utf8.parse(CryptoJS.MD5(k))
生成key,后端就解密失败,如果是key固定,iv动态生成,解密仍成功,唯独Key动态时失败
也可能是学艺不精,所以来此询问下各位,多多指点 谢谢
动态的key需要截取来固定长度,iv不报错是动态的iv也是固定的长度