crypto.subtle.encrypt() 必须在 filereader 读取 arraybuffer 后调用,不可直接操作 file 对象;必须用 readasarraybuffer() 获取二进制数据,禁用 readasdataurl();大文件需分块+web worker 加密,aes-gcm 是唯一推荐算法,iv 必须每次随机生成 12 字节并独立传输,密钥不得硬编码,服务端必须校验 authtag 并拒绝降级。

crypto.subtle.encrypt() 必须在 FileReader 读取 ArrayBuffer 后调用
上传前加密不是对 <input type="file"> 元素本身操作,而是对文件内容的二进制表示加密。浏览器不让你直接访问原始磁盘文件,必须先用 FileReader.readAsArrayBuffer() 把它读成内存中的 ArrayBuffer,之后才能传给 crypto.subtle.encrypt()。跳过这步、试图对 File 对象直接加密会报错或返回空。
常见错误现象:TypeError: Cannot read property 'encrypt' of undefined(没走 HTTPS)、DOMException: The operation is not allowed in this context(HTTP 页面调用)、或加密后上传的密文解不开(误用了 readAsDataURL() 得到 base64 字符串再转 ArrayBuffer,造成数据膨胀和编码失真)。
- 永远不用
readAsDataURL()做加密准备——base64 编码体积增加 33%,且字符串比Uint8Array更难安全擦除 - 大文件(>100MB)建议分块读取:用
file.slice(start, end)+ 多次FileReader,避免内存爆掉 - 读完立即清空明文缓冲区:
new Uint8Array(arrayBuffer).fill(0),尤其在 Worker 中更关键
AES-GCM 是唯一推荐的加密方式,IV 必须每次随机生成
AES-GCM 是目前 Web Crypto API 中唯一同时提供机密性与完整性验证的算法。用 AES-CBC 或手写 RC4 等等,等于没加——攻击者可篡改密文而不被发现。IV(初始化向量)不是“随便填个数”,必须每次加密都调用 crypto.getRandomValues(new Uint8Array(12)) 生成全新值,长度固定为 12 字节(GCM 标准要求),且必须随密文一起发给后端。
容易踩的坑:iv 被硬编码成固定值(如 new Uint8Array([0,1,2,...])),导致相同明文产生相同密文,可被统计分析;或把 iv 拼进密文二进制流却不告诉后端长度,导致解密失败。
- 服务端必须能解析出独立的
iv字段(例如 JSON body 中显式传{"iv": "base64string", "ciphertext": "..."}) - 不要把
iv和密文混在一起再 base64 —— 解密时无法可靠分离 - 密钥绝不能写死在 JS 里;推荐用服务端 RSA 公钥加密临时 AES 密钥,或用户口令 + PBKDF2 派生(需 salt 随机)
Web Worker 是处理大文件加密的必要手段
主线程执行 AES-GCM 加密 >50MB 文件时,页面必然卡死甚至崩溃。这不是性能优化问题,而是浏览器线程模型决定的——加密是同步 CPU 密集型操作,必须移出主线程。用 Web Worker 不仅防卡顿,还能隔离密钥使用上下文,降低 XSS 泄露风险。
典型错误是“在主线程切片、再把每片 ArrayBuffer 发给 Worker 加密”——这会导致大量数据拷贝,拖慢整体速度。正确做法是:Worker 内部直接调用 file.slice() + FileReader,加密完立刻 postMessage({ encryptedBytes, iv, authTag }, [encryptedBytes.buffer]) 使用 Transferable 避免拷贝。
- 主线程只负责创建 Worker、监听进度、发起上传请求(含认证头、断点续传逻辑)
- Worker 不发网络请求,只产出加密载荷;否则重试、超时、并发控制全乱套
- 多个文件上传时,每个文件应独占一个 Worker 实例,避免密钥/IV 混淆
服务端必须校验 GCM authTag,且拒绝降级请求
前端加密只是传输环节的保护,服务端才是可信边界。如果后端收到请求却只解密、不验证 authTag,就等于开了个后门——攻击者可任意修改密文,只要凑出能通过 AES 解密的字节流,就能绕过完整性校验。
另一个高频疏漏:后端接受不带 iv 或 algorithm 字段的请求,或 fallback 到明文接收。这会让整个加密形同虚设,且极易被自动化工具探测并降级利用。
- 请求体缺失
iv、authTag或algorithm字段,直接 400,不进业务逻辑 - 解密失败一律返回通用错误(如
{"error":"invalid_payload"}),绝不暴露 “IV mismatch” 或 “authTag verification failed” - 解密后的明文文件必须写入非 Web 可访问路径,处理完立即
unlink(),禁止日志记录原始二进制
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











