CryptoJS 如何安全存储Passphrase 避免其明文暴露在JS文件中
问题解答
你说的没错,把Passphrase明文写在JS文件里完全没有加密意义,所有访问页面的用户都可以直接通过查看源码拿到密钥,加密等于形同虚设。
你想到的Ajax获取密钥后存在Cookie的方案不可行,存在多个安全漏洞:
- 如果Cookie设置了
HttpOnly属性,你的前端JS根本无法读取到Cookie值,没法用来加密;如果没设HttpOnly,只要站点存在XSS漏洞,攻击者可以直接窃取到密钥。 - 密钥通过Ajax从服务端获取,意味着服务端本身持有密钥,不符合端到端加密的设计目标,而且如果没有HTTPS传输,密钥中途会被中间人截获。
- 就算用户登出时删除Cookie,依然存在本地存储残留被数据恢复工具获取的风险。
可落地的最佳实践
- 最高安全级方案:密钥完全由用户自主输入,不做任何持久化存储。用户每次需要执行加密/解密操作时,弹窗引导用户输入Passphrase,密钥仅临时保存在JS运行内存中,操作完成后立即销毁变量,不要存入Cookie、
LocalStorage、SessionStorage等任何本地存储区域,也永远不要将密钥上传到服务端,完全符合端到端加密的安全要求。 - 降低用户输入成本的折中方案:采用密钥派生方案,用户首次输入Passphrase后,使用
PBKDF2、Argon2等慢哈希密钥派生算法,结合用户端随机生成的盐值派生出实际加密用的密钥,盐值可以明文存在LocalStorage里,Passphrase本身不做任何存储。后续用户使用时仅需输入Passphrase,用本地存储的盐值重新派生密钥即可,全程不需要和服务端交互传输密钥相关信息。 - 进阶优化:优先使用浏览器原生的
Web Crypto API替代CryptoJS做加密操作,原生API支持将密钥标记为不可导出,就算出现XSS漏洞也没法直接拿到密钥明文,安全等级远高于纯JS实现的加密库。
内容的提问来源于stack exchange,提问作者nerran
相关产品推荐
相关产品推荐

