为什么我在 crypto-js 上收到格式错误的 UTF-8 数据错误?
Why I get Malformed UTF-8 data error on crypto-js?
我尝试使用 crypto-js
:
来加密和解密这个字符串
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~3~null~undefined~434ce0149ce42606d8746bd9`;
但是我得到一个错误:
Error: Malformed UTF-8 data
我做错了什么?我该如何解决?
完整代码also on stackbliz:
import crypto from 'crypto-js';
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~9~null~undefined~434ce0149ce42606d8746bd9`;
const cryptoInfo = crypto.AES.encrypt(str, 'secret').toString();
console.log({ cryptoInfo });
const info2 = crypto.AES.decrypt(str, 'secret').toString(crypto.enc.Utf8);
console.log({ info2 });
不知道为什么,但您必须用一个对象包裹您的字符串并使用JSON.stringify
才能使其工作。
这里:
import crypto from 'crypto-js';
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~9~null~undefined~434ce0149ce42606d8746bd9`;
const cryptoInfo = crypto.AES.encrypt(JSON.stringify({ str }), 'secret').toString();
console.log({ cryptoInfo });
const info2 = crypto.AES.decrypt(cryptoInfo, 'secret').toString(crypto.enc.Utf8);
console.log({ info2 });
const info3 = JSON.parse(info2);
console.log({ str: info3.str });
我加密了一个名称并将其作为 URL 参数传递。
我很惊讶,解密代码不起作用
这是因为加密参数中生成的“+”字符。然后使用“encodeURIComponent”和“decodeURIComponent”它起作用了。
<script>
jQuery("#myBtn").click(function(){
var clientname= jQuery("#myInput").val();
var encrypted = CryptoJS.AES.encrypt(clientname, "secret key 123");
//my URL to call with encrypted client name
jQuery("#output").append('<small id="myurl">https://www.xxxxx.com/?id='+encodeURIComponent(encrypted)+"</small>");
});
</script>
var urlParams = new URLSearchParams(window.location.search);
var crypted_param = decodeURIComponent(urlParams.get('id'));
if(crypted_param && crypted_param != null && crypted_param != "" && crypted_param != "null"){
var decrypted = CryptoJS.AES.decrypt(crypted_param, "secret key 123");
jQuery('#output1').val(decrypted.toString(CryptoJS.enc.Utf8));
}
您忘记将加密文本作为参数传递给解密函数。
在解密函数中,您传递的是原始字符串,即 'str',这是导致上述代码出现问题的原因,这里是正确的代码。
import crypto from "crypto-js";
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~9~null~undefined~434ce0149ce42606d8746bd9`;
const cryptoInfo = crypto.AES.encrypt(JSON.stringify(str), "secret");
console.log({cryptoInfo});
const info2 = crypto.AES.decrypt(cryptoInfo.toString(), 'secret').toString(crypto.enc.Utf8);
console.log({ info2 });
我已经解决了清理本地存储的问题。
尽管有上述所有建议,请检查您的加密密钥和秘密密钥。解密时 加密密钥 应与您在加密时使用的 加密密钥 匹配。
我遇到了同样的问题,加密后的值似乎是base64,需要先转换成utf-8。
示例:
const utf8 = CryptoJS.enc.Base64.parse(value);
const decrypted = CryptoJS.DES.decrypt({ ciphertext: utf8 }, keyWords, { iv: ivWords });
我找到了解决方案Here
我尝试使用 crypto-js
:
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~3~null~undefined~434ce0149ce42606d8746bd9`;
但是我得到一个错误:
Error: Malformed UTF-8 data
我做错了什么?我该如何解决?
完整代码also on stackbliz:
import crypto from 'crypto-js';
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~9~null~undefined~434ce0149ce42606d8746bd9`;
const cryptoInfo = crypto.AES.encrypt(str, 'secret').toString();
console.log({ cryptoInfo });
const info2 = crypto.AES.decrypt(str, 'secret').toString(crypto.enc.Utf8);
console.log({ info2 });
不知道为什么,但您必须用一个对象包裹您的字符串并使用JSON.stringify
才能使其工作。
这里:
import crypto from 'crypto-js';
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~9~null~undefined~434ce0149ce42606d8746bd9`;
const cryptoInfo = crypto.AES.encrypt(JSON.stringify({ str }), 'secret').toString();
console.log({ cryptoInfo });
const info2 = crypto.AES.decrypt(cryptoInfo, 'secret').toString(crypto.enc.Utf8);
console.log({ info2 });
const info3 = JSON.parse(info2);
console.log({ str: info3.str });
我加密了一个名称并将其作为 URL 参数传递。 我很惊讶,解密代码不起作用 这是因为加密参数中生成的“+”字符。然后使用“encodeURIComponent”和“decodeURIComponent”它起作用了。
<script>
jQuery("#myBtn").click(function(){
var clientname= jQuery("#myInput").val();
var encrypted = CryptoJS.AES.encrypt(clientname, "secret key 123");
//my URL to call with encrypted client name
jQuery("#output").append('<small id="myurl">https://www.xxxxx.com/?id='+encodeURIComponent(encrypted)+"</small>");
});
</script>
var urlParams = new URLSearchParams(window.location.search);
var crypted_param = decodeURIComponent(urlParams.get('id'));
if(crypted_param && crypted_param != null && crypted_param != "" && crypted_param != "null"){
var decrypted = CryptoJS.AES.decrypt(crypted_param, "secret key 123");
jQuery('#output1').val(decrypted.toString(CryptoJS.enc.Utf8));
}
您忘记将加密文本作为参数传递给解密函数。
在解密函数中,您传递的是原始字符串,即 'str',这是导致上述代码出现问题的原因,这里是正确的代码。
import crypto from "crypto-js";
const str = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI1ZDg5MjMxMjc5OTkxYjJhNGMwMjdjMGIiLCJoc2giOiIkMmEkMTMkWk53Y0cubjdRZFIybDA3S1RHd2RoLlN0QksudW5GSFVGLkZnZ0tQTGlUV2pOVEFqVy9SMm0iLCJncmFudCI6ImFjY2VzcyIsImlhdCI6MTU2OTI2ODUwMiwiZXhwIjoxNjAwODI2MTAyfQ.PQcCoF9d25bBqr1U4IhJbylpnKTYiad3NjCh_LvMfLE~9~null~undefined~434ce0149ce42606d8746bd9`;
const cryptoInfo = crypto.AES.encrypt(JSON.stringify(str), "secret");
console.log({cryptoInfo});
const info2 = crypto.AES.decrypt(cryptoInfo.toString(), 'secret').toString(crypto.enc.Utf8);
console.log({ info2 });
我已经解决了清理本地存储的问题。
尽管有上述所有建议,请检查您的加密密钥和秘密密钥。解密时 加密密钥 应与您在加密时使用的 加密密钥 匹配。
我遇到了同样的问题,加密后的值似乎是base64,需要先转换成utf-8。 示例:
const utf8 = CryptoJS.enc.Base64.parse(value);
const decrypted = CryptoJS.DES.decrypt({ ciphertext: utf8 }, keyWords, { iv: ivWords });
我找到了解决方案Here