CryptoJS 解密 Malformed UTF-8 数据错误

CryptoJS decryption Malformed UTF-8 data error

我尝试加密和解密对象。加密工作正常,它变成加密字符串。但是描述函数总是返回我 "Malformed UTF-8 data error"

对象

var data = {
        'City': 1,
        'DisplayOrder': 20,
        'Semantic': [{'Value': '1','Description': [{'value': 'string'}],
        'aff': [{'Id': '2','Name': 'Feature1','FeatureOptions': [{'Key': 'Key1','Value': 'Value1'},{    'Key': 'Key2','Value': 'Value2'}],
        'SelectedFeatureOption': {    'Key': 'Key1',    'Value': 'Value1'}}],'aff1': [{'Key': 'Key1','Value':'Value1'}]
        }]
    }

加密

function encryptData2(data) {
var Key = C.enc.Utf8.parse("6il7YCRSqIOB9NooY225lPKQ0KuAF/nkFX6cY3vJkS0=");
        var IV = CryptoJS.enc.Utf8.parse("0123456789ABCDEF");
        var encryptedText = CryptoJS.AES.encrypt(JSON.stringify(data), Key, {
            iv: IV,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
        return encryptedText.toString(CryptoJS.format.Hex);
    }
    var encryptedData = encryptData2(data);

解密

 var decryptData2 = function(encryptedData, key) {
        var C = CryptoJS;
        encryptedData = C.enc.Base64.parse(encryptedData);
var Key = C.enc.Utf8.parse("6il7YCRSqIOB9NooY225lPKQ0KuAF/nkFX6cY3vJkS0=");
        var IV = C.enc.Utf8.parse("0123456789ABCDEF");
        var decryptedText = C.AES.encrypt(encryptedData, Key, {
            iv: IV,
            mode: C.mode.CBC,
            padding: C.pad.Pkcs7
        });
        return encryptedData.toString(CryptoJS.enc.Utf8)
    }

    var result = decryptData2(encryptedData);

如何解决?

由于 encrypt- 和 decrypt- 方法都处理各种数据类型(参见 The Cipher Input and The Cipher Output),因此有多种方法可以解决 encryptData2 之间的不兼容问题和 decryptData2。一种可能性是:

const CryptoJS = require("crypto-js");

var data = {
    'City': 1,
    'DisplayOrder': 20,
    'Semantic': [{'Value': '1','Description': [{'value': 'string'}],
    'aff': [{'Id': '2','Name': 'Feature1','FeatureOptions': [{'Key': 'Key1','Value': 'Value1'},{    'Key': 'Key2','Value': 'Value2'}],
    'SelectedFeatureOption': {    'Key': 'Key1',    'Value': 'Value1'}}],'aff1': [{'Key': 'Key1','Value':'Value1'}]
    }]
}

function encryptData2(data) {
    //var Key = C.enc.Utf8.parse("6il7YCRSqIOB9NooY225lPKQ0KuAF/nkFX6cY3vJkS0=");
    var Key = CryptoJS.enc.Utf8.parse("6il7YCRSqIOB9NooY225lPKQ0KuAF/nkFX6cY3vJkS0=");  // 1. Replace C by CryptoJS
    var IV = CryptoJS.enc.Utf8.parse("0123456789ABCDEF");
    var encryptedText = CryptoJS.AES.encrypt(JSON.stringify(data), Key, {
        iv: IV,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    //return encryptedText.toString(CryptoJS.format.Hex);
    return encryptedText.toString(CryptoJS.format.Base64);                              // 2. Use Base64 instead of Hex
}
var encryptedData = encryptData2(data);

var decryptData2 = function(encryptedData, key) {
    var C = CryptoJS;
    //encryptedData = C.enc.Base64.parse(encryptedData);                                // 3. Remove line
    var Key = C.enc.Utf8.parse("6il7YCRSqIOB9NooY225lPKQ0KuAF/nkFX6cY3vJkS0=");
    var IV = C.enc.Utf8.parse("0123456789ABCDEF");
    //var decryptedText = C.AES.encrypt(encryptedData, Key, {
    var decryptedText = C.AES.decrypt(encryptedData, Key, {                             // 4. Use decrypt instead of encrypt
        iv: IV,
        mode: C.mode.CBC,
        padding: C.pad.Pkcs7
    });
    //return encryptedData.toString(CryptoJS.enc.Utf8);
    return decryptedText.toString(CryptoJS.enc.Utf8);                                   // 5. Use decryptedText instead of encryptedData
}

var result = decryptData2(encryptedData);
console.log(result); 

附带说明一下,密钥似乎是 Base64 编码的,因此最好这样解析:

var Key = CryptoJS.enc.Base64.parse("6il7YCRSqIOB9NooY225lPKQ0KuAF/nkFX6cY3vJkS0=");

更新:

按照@kelalaka 的建议,decryptData2 通常应该return 一个JSON 对象,因为JSON 对象也被传递给encryptData2。在这种情况下,decryptData2 中的 JSON 字符串在 returned 时必须转换为 JSON 对象,例如与:

return JSON.parse(decryptedText.toString(CryptoJS.enc.Utf8));