应使用 web crypto api 替代纯 js 加密库,并将 rsa、pbkdf2 等重操作卸载至 web worker;预生成复用密钥与 iv,仅加密敏感字段,长文本及文件交由服务端处理。

前端加密解密操作(尤其是RSA模幂、AES多轮迭代、PBKDF2密钥拉伸)容易成为长任务,阻塞主线程,导致页面卡顿、输入延迟甚至渲染掉帧。优化不是靠“写得更巧”,而是围绕浏览器执行机制做针对性调整:把重计算移出主线程、减少重复开销、用原生能力替代JS模拟。
用 Web Crypto API 替代第三方库
像 CryptoJS、JSEncrypt 这类纯 JS 实现的库,本质是用 JavaScript 模拟大数运算和密码学原语,性能远低于浏览器底层实现。Web Crypto API 是 W3C 标准,由浏览器用 C++/Rust 实现,AES-GCM 加密速度通常快 5–10 倍,SHA-256 哈希快 3 倍以上,且支持硬件加速(如 Intel AES-NI)。
- 替换 CryptoJS.AES.encrypt →
crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data) - 替换 JSEncrypt.encrypt →
crypto.subtle.encrypt({ name: 'RSA-OAEP' }, publicKey, data) - 注意:Web Crypto 只在 HTTPS 或 localhost 下可用,密钥需用
importKey导入,不能直接传字符串
将加密任务卸载到 Web Worker
即使使用 Web Crypto,RSA-2048 解密或 PBKDF2 衍生密钥仍可能耗时 50–200ms。这类操作必须脱离主线程,否则会冻结 UI(尤其在低端安卓机上)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 新建
encrypt-worker.js,用self.onmessage接收明文、算法参数和密钥材料 - 在 worker 内调用
crypto.subtle,完成后self.postMessage({ result, type: 'encrypted' }) - 主线程通过
worker.postMessage()发送数据,监听message事件获取结果 - 敏感密钥(如 RSA 私钥)切勿传入 worker —— worker 与主线程内存隔离,无法共享
CryptoKey对象;应提前在主线程完成密钥导入,再用structuredClone(Chrome 98+)或序列化方式传递公钥/加密参数
预生成并复用密钥与 IV
每次加密都重新生成随机 IV 或派生密钥,不仅浪费 CPU,还可能因 PRNG 调用引入不确定延迟。对固定场景可提前准备:
- AES 场景:登录态 token 加密,可复用同一组密钥 + 随机 IV(IV 存入 localStorage 或拼入响应体),避免每次调用
crypto.getRandomValues() - RSA 场景:公钥加密无需 IV;若用于加密 AES 会话密钥,可预先生成好临时 AES 密钥,再用 RSA 公钥加密它,比直接加密长数据更高效
- PBKDF2 场景:盐值(salt)和迭代次数固定时,可缓存派生出的
CryptoKey,后续直接复用,跳过耗时的哈希循环
控制输入规模,避免加密整包数据
前端加密不是越“全”越好。加密整个 JSON 请求体(含非敏感字段)既无必要,又放大计算负担。
- 只加密真正敏感字段:如密码、身份证号、银行卡号,其余字段走明文(HTTPS 已保障传输安全)
- 对长文本(如用户评论)改用服务端加密:前端仅计算签名(HMAC-SHA256)保证完整性,加密交由后端完成
- 上传文件前不前端加密:大文件 RSA 加密不可行,AES 分块加密易出错;应走后端直传 + 服务端加密流程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










