不能安全地用 localStorage 存储用户敏感信息,必须通过 Web Crypto + AES-GCM 加密、密钥隔离与行为约束降低风险,且密钥绝不可硬编码或存于前端存储。

不能安全地用 localStorage 存储用户敏感信息——这是前提。它本身不加密、无访问控制、易被 XSS 窃取,浏览器也明确不提供保护机制。所谓“安全读写”,实际是指:在必须前端暂存的场景下,通过加密+密钥隔离+行为约束,把风险压到最低。
先确认哪些数据真不该进 localStorage
以下内容绝对禁止直接存入:
• 用户密码、身份证号、银行卡号
• JWT token、OAuth access_token、API 密钥
• 会话凭证(如 session_id)、一次性验证码
• 加密后的密钥、主密码哈希值
这些应由后端管理,前端只持短期、受限、HttpOnly 的 Cookie 或内存变量。
如果非存不可,必须走 Web Crypto + AES-GCM 流程
仅当满足两个条件时才考虑加密存储:
- 数据生命周期极短(如临时表单草稿、离线待同步的脱敏日志)
- 用户明确知情并主动输入口令参与加解密(如密码管理器类应用)
- 用
crypto.subtle.importKey导入密钥时,指定length: 256,算法为"AES-GCM" - 每次加密前调用
crypto.getRandomValues(new Uint8Array(12))生成 12 字节 IV,绝不复用 - 密文、IV、salt(若用 PBKDF2 派生)统一打包成对象,再
JSON.stringify存入:{ iv: "base64...", data: "base64...", salt: "base64..." } - 解密前必须校验认证标签(GCM 自动完成),失败即丢弃整条数据
密钥管理是成败关键,没有例外
密钥绝不能:
• 出现在源码里(硬编码)
• 存在 localStorage / sessionStorage / URL / cookie 中
• 从不受信接口或 DOM 属性中读取
- 推荐方案一(用户口令驱动):用
PBKDF2+ 随机 salt 派生密钥,salt 和密文一起存,口令仅内存暂存 - 推荐方案二(会话级):登录后由后端返回一次性对称密钥(经 RSA 公钥加密),解密后仅存在 JS 变量中,页面卸载前清空
- 永远不用
localStorage.getItem("key")读密钥——这等于没加密
配套防御不能少
加密只是其中一环,还需叠加:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 启用严格 CSP(禁止内联脚本、限制
eval),大幅降低 XSS 成功率 - 所有敏感操作(如解密、提交)前检查当前上下文是否为 HTTPS 或 localhost
- 监听
storage事件时,不响应来自非预期来源的变更(可加签名或时间戳验证) - 定期调用
localStorage.removeItem()清理过期项,避免堆积泄露面
本质上,前端加密不是保险箱,而是给攻击者加一道需要时间和工具的门槛。真正敏感的数据,始终该留在服务端可控环境中。
立即学习“前端免费学习笔记(深入)”;


















