必须在应用层做端到端加密,采用rsa传递aes密钥+aes-gcm加密消息的混合加密方案,密钥会话级隔离、iv每次唯一、严格使用web crypto api。

WebSocket 文本数据不能只靠 wss:// 协议来保障安全。wss 只加密传输链路,服务端日志、内存、内网转发、浏览器调试器甚至 XSS 跨 Tab 攻击,都可能拿到明文。真正保护消息内容,必须在应用层做端到端加密。
必须用混合加密:RSA 传密钥 + AES 加消息
纯 RSA 加密长文本慢、有长度限制、不带 IV,不适合实时消息;硬编码 AES 密钥一旦泄露,全量数据失守。正确做法是:
- 前端每次新建 WebSocket 连接前,先通过 HTTPS 接口获取服务端 RSA 公钥(建议带签名校验)
- 连接建立后,前端生成一个 32 字节的随机 AES-256 密钥和一个 12 字节随机 IV
- 用服务端公钥加密该 AES 密钥,连同 base64 编码的 IV 和加密后的消息体一起发给服务端
- 后续所有消息均使用该 AES 密钥 + 每次唯一 IV,推荐 AES-GCM 模式(含认证标签 tag,防篡改)
前端加密要严格遵循 Web Crypto API 规范
别用 CryptoJS 等第三方库,优先调用浏览器原生 window.crypto.subtle:
- 用
TextEncoder将 JSON 字符串转为Uint8Array,避免中文乱码 - AES 密钥必须动态生成:
crypto.subtle.generateKey('AES-GCM', true, ['encrypt', 'decrypt']) - IV 每次调用
crypto.getRandomValues(new Uint8Array(12))生成,绝不可复用 - RSA 公钥导入前需去除 PEM 头尾(
-----BEGIN PUBLIC KEY-----等),base64 解码后再用importKey
消息结构要统一且可扩展
建议发送时采用固定格式,便于后端路由和审计:
{ "encryptedKey": "base64...", "iv": "base64...", "data": "base64...", "ts": 1727769800 }-
ts是时间戳,服务端可校验时效性(如 30 秒内有效) - 若需角色化控制(如管理员看全量、普通用户看掩码),可在 AAD(附加认证数据)中加入
client_id或role字段,由服务端在解密前校验 - 服务端只透传加密载荷,不解密——即使经过 Cloudflare 或 Nginx,也应配置 TLS 直通
密钥生命周期必须会话级隔离
安全的关键在于“用完即弃”:
- AES 密钥和 IV 仅在本次 WebSocket 连接生命周期内有效
- 连接关闭或重连时,必须丢弃旧密钥,重新生成新密钥对
- 密钥绝不存入 localStorage、Cookie、URL 参数或全局变量(如
window.key) - sessionStorage 可临时存公钥,但私钥永远不出服务端
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











