Vue组件里用Web Crypto加密后的数据在服务端无法解密怎么办?
我在做一个聊天功能时用Vue实现端到端加密,按照文档用Web Crypto的subtle加密了消息内容,但服务端返回”无法解密”的错误。试过把加密结果转成Base64,但后端说数据格式不对。
这是我的加密代码片段,发送前调用encryptMessage:
<script>
export default {
methods: {
async encryptMessage(text) {
const encoder = new TextEncoder();
const data = encoder.encode(text);
const key = await crypto.subtle.generateKey(
{ name: "AES-CBC", length: 256 },
true,
["encrypt"]
);
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-CBC", iv: iv },
key,
data
);
return new TextDecoder().decode(encrypted); // 这里有问题吗?
}
}
}
</script>
测试时发现返回的加密数据全是乱码,用同样的密钥在后端尝试解密时提示”Invalid ciphertext”。我应该检查密钥的传递方式还是加密参数?有没有前端常见的加密格式误区?
Web Crypto的encrypt返回的是ArrayBuffer,你用TextDecoder.decode()转成字符串会损失数据。因为加密结果是二进制流,不是文本编码。乱码是必然的,后端当然解不出来。
你该这么做:
1. 把加密结果转成Uint8Array
2. 再用base64编码传给后端
另外你的密钥生成也有问题。AES-CBC密钥应该固定,不能每次都generateKey。你现在每次加密都生成新密钥,后端拿啥解密?
你应该:
- 前端用importKey导入后端给的公钥
- 或者用固定密钥(虽然不推荐)
- 更稳妥的是用非对称加密(RSA-OAEP)
建议你让后端提供具体加密算法和密钥格式要求。前后端加密方式要严格一致,参数一个都不能差。前端这块加密最坑的就是数据格式转换,二进制处理不规范直接导致解密失败。