前端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动态时失败
也可能是学艺不精,所以来此询问下各位,多多指点 谢谢

讨论数量: 1

动态的key需要截取来固定长度,iv不报错是动态的iv也是固定的长度

11个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!