PHP全栈狼 2023-12-03 23:34 采纳率: 42.9%
浏览 26
已结题

后端PHP 前端vuejs ,使用AES对称加密的问题

后端代码:

private $method = 'AES-256-CBC';

      // 加密
    public function encrypt($data, $keys) {
        $key = hash('sha256', $keys, true);
        $ivLength = openssl_cipher_iv_length($this->method);
        $iv = openssl_random_pseudo_bytes($ivLength);
        $ivBase64 = base64_encode($iv);
        var_dump('iv:'.$ivBase64);
        $encrypted = openssl_encrypt($data, $this->method, $key, 0, $iv);
        $ivBase64data = base64_encode($encrypted);
        var_dump('data:'.$ivBase64data);
        $encrypted = base64_encode($iv . $encrypted);
        $base64_key = base64_encode($key);
        var_dump('key:'.$base64_key);
        var_dump('decrypt:'.$this->decrypt($encrypted,$keys));
        return $encrypted;
    }
//解密
    public function decrypt($data, $keys) {
        $key = hash('sha256', $keys, true);
        $data = base64_decode($data);
        $ivLength = openssl_cipher_iv_length($this->method);
        $iv = substr($data, 0, $ivLength);
        $data = substr($data, $ivLength);
        $decrypted = openssl_decrypt($data, $this->method, $key, 0, $iv);
        return $decrypted;
    }

前端解密:

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
 decrypt(encryptedMessage, secretKey) {
const rawEncryptedMessage = CryptoJS.enc.Base64.parse(encryptedMessage);
                
                    // 假设IV是消息的前16个字节
                    const iv = CryptoJS.lib.WordArray.create(rawEncryptedMessage.words.slice(0, 4));
                    
                    // 密文是Base64解码后的消息去掉前16字节的IV部分
                    
                    const ciphertext  = CryptoJS.lib.WordArray.create(rawEncryptedMessage.words.slice(4));

                   
                    // 生成密钥,SHA256返回的散列值正好是256位(32字节)
                   
                    const key = CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(secretKey));
                    // 解密
                    const decrypted = CryptoJS.AES.decrypt({ciphertext:ciphertext}, key, {
                        iv: iv,
                        mode: CryptoJS.mode.CBC,
                        padding: CryptoJS.pad.Pkcs7
                    });
                    
                    const ivBase64 = CryptoJS.enc.Base64.stringify(iv);
                    console.log(' IV:', ivBase64);
                    const base64datas = CryptoJS.enc.Base64.stringify(ciphertext);
                    console.log('data:', base64datas);
                    const base64Key = CryptoJS.enc.Base64.stringify(key);
                    console.log('Key:', base64Key);
                    
                    // 将解密结果转换为Utf8字符串
                    return decrypted.toString(CryptoJS.enc.Utf8);
}

后端加密打印
"iv:6PpM55NjDGQwelE1kqE28A=="
"data:MFJQUUFMNFJpZnVGdk12Mm0xZkRoQTZ6by8vZmdWNmptdXlxK2phcitGWT0="
"key:5UAauWHS/fD2CuOgXy8+ZVZbFvA6C1dagnnq0zWaDyE="
"decrypt:privatekey156ds4a564d5s6ad"
前端解密打印结果
IV: 6PpM55NjDGQwelE1kqE28A==
data: MFJQUUFMNFJpZnVGdk12Mm0xZkRoQTZ6by8vZmdWNmptdXlxK2phcitGWT0=
Key: 5UAauWHS/fD2CuOgXy8+ZVZbFvA6C1dagnnq0zWaDyE=

IV 密文 秘钥三项都是一致的
麻烦各位帮忙分析一下问题:
但是解密出来时 有时空字符empty string 有时其他字符串 ‘XY’ 有时报错 ‘Malformed UTF-8 data’

  • 写回答

2条回答 默认 最新

  • PHP全栈狼 2023-12-04 00:08
    关注

    openssl_encrypt($data, $this->method, $key, OPENSSL_RAW_DATA, $iv);

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月10日
  • 已采纳回答 12月4日
  • 修改了问题 12月3日
  • 修改了问题 12月3日
  • 展开全部