后端crypto加密数据,已知密钥与IV如何前端解密?
问题:已知密钥(secret)和初始化向量(IV),能否在前端解密后端如下代码加密的数据?
后端加密代码:
const algorithm = 'aes-256-ctr'; // const algorithm = 'aes-128-cbc'; let inVec = crypto.randomBytes(16); const secret = 'salted'; const key = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 32); const cipher = crypto.createCipheriv(algorithm, key, key.substr(0, 16)) let encrypt = cipher.update(name, 'utf8', 'base64') encrypt = encrypt + cipher.final();
回答:
可以在前端完成解密,但必须严格对齐后端的加密逻辑,核心注意事项如下:
- 算法严格匹配:前端必须使用和后端一致的加密算法(
aes-256-ctr或aes-128-cbc) - 复刻密钥生成流程:
- 对已知的secret执行SHA256哈希计算
- 将哈希结果转换为Base64格式
- 截取该Base64字符串的前32位,得到与后端完全一致的key
- IV的正确取值:注意你提供的后端代码中,生成的
inVec并未实际使用,真正的IV是上述key的前16位,前端解密时必须用这个值作为初始化向量 - 前端工具选择:可以使用浏览器原生的Web Crypto API,或者第三方加密库(如CryptoJS)实现解密,只要能正确处理对应AES算法、密钥和IV即可
以下是基于Web Crypto API的AES-256-CTR解密示例:
async function decrypt(encryptedData, secret) { // 复刻后端密钥生成逻辑 const encoder = new TextEncoder(); const secretHash = await crypto.subtle.digest('SHA-256', encoder.encode(secret)); const keyBase64 = btoa(String.fromCharCode(...new Uint8Array(secretHash))); const keyStr = keyBase64.substr(0, 32); const ivStr = keyStr.substr(0, 16); // 将密钥和IV转为二进制格式 const keyBuffer = Uint8Array.from(atob(keyStr), c => c.charCodeAt(0)); const ivBuffer = Uint8Array.from(atob(ivStr), c => c.charCodeAt(0)); // 导入密钥 const key = await crypto.subtle.importKey( 'raw', keyBuffer, { name: 'AES-CTR' }, false, ['decrypt'] ); // 解密并转换为明文 const encryptedBuffer = Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0)); const decryptedBuffer = await crypto.subtle.decrypt( { name: 'AES-CTR', counter: ivBuffer, length: 128 }, key, encryptedBuffer ); return new TextDecoder().decode(decryptedBuffer); }
内容的提问来源于stack exchange,提问作者thomas paulson
相关产品推荐
相关产品推荐

