WebAssembly 里怎么安全地做加密解密?

东方爱菊 阅读 2

我用 Rust 编译了一个 WebAssembly 模块,想在前端做 AES 加密解密,但密钥如果写在 JS 里感觉不安全。

试过把密钥传给 wasm 函数,但发现浏览器 devtools 还是能抓到调用参数。有没有办法让密钥完全不经过 JS 层?

比如能不能在 wasm 内部生成或存储密钥?或者有其他更安全的方案?

#[wasm_bindgen]
pub fn decrypt(data: &[u8], key: &[u8]) -> Vec<u8> {
    // 使用 aes-gcm 或类似 crate 解密
    // 但 key 是从 JS 传进来的,担心被拦截
}
我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
宇文令敏
这个需求确实头疼,前端搞加密永远是个安全与方便的权衡问题。说几个可行的方案:

1. 最安全的方案是让wasm自己生成密钥,完全不暴露给JS层:
#[wasm_bindgen]
pub fn generate_key() -> Vec<u8> {
let key = [0u8; 32]; // 实际应该用安全的随机生成
key.to_vec()
}

然后在wasm内部用这个密钥加解密。缺点是每次刷新都会变,适合临时会话场景。

2. 如果必须用固定密钥,试试把密钥编译进wasm二进制:
const HARDCODED_KEY: &[u8] = &[1,2,3...]; // 实际应该用build脚本动态生成

#[wasm_bindgen]
pub fn decrypt(data: &[u8]) -> Vec<u8> {
// 直接使用HARDCODED_KEY
}

这样密钥不会出现在JS内存里,但wasm文件本身还是可能被反编译。

3. 终极方案是结合服务端,前端只负责加密不负责密钥管理。wasm生成临时密钥加密数据,把加密后的数据和密钥(再用服务端公钥加密一次)一起发给后端解密。

说实话在前端搞安全加密就是个伪命题,真要安全还得靠后端。不过wasm至少比纯JS安全点,至少不会被轻易console.log出来。
点赞
2026-03-06 12:26