浏览器端加密实战:Web Crypto API与国密SM2/SM3/SM4的实现路径

前端安全(更新于 2026年5月18日)

为什么要在浏览器端做加密?

传统加密流程需要将数据发送到服务器处理,这带来了隐私风险:

传统:明文 → 网络传输 → 服务器加密 → 密文返回
风险:明文可能被截获,服务器可能记录

浏览器端:明文 → 本地加密 → 密文
优势:明文从未离开用户设备

工具库的加密解密模块(30+ 工具)全部在浏览器本地完成,用户数据零上传。


Web Crypto API:浏览器原生加密

核心能力

Web Crypto API 是 W3C 标准,所有现代浏览器均支持:

// 检测支持
if (window.crypto?.subtle) {
  // 支持 Web Crypto API
}
算法类别 支持的算法 密钥长度
对称加密 AES-GCM, AES-CBC, AES-CTR 128/192/256
非对称加密 RSA-OAEP, RSA-PSS, ECDSA 2048/4096
密钥派生 PBKDF2, HKDF, ECDH -
哈希 SHA-1, SHA-256, SHA-384, SHA-512 -
HMAC HMAC (配合以上哈希) -

AES-256-GCM 完整实现

async function aesGcmEncrypt(plaintext: string, password: string) {
  const enc = new TextEncoder();

  // 1. 从口令派生密钥(PBKDF2)
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const keyMaterial = await crypto.subtle.importKey(
    'raw', enc.encode(password), 'PBKDF2', false, ['deriveKey']
  );
  const key = await crypto.subtle.deriveKey(
    { name: 'PBKDF2', salt, iterations: 600000, hash: 'SHA-256' },
    keyMaterial,
    { name: 'AES-GCM', length: 256 },
    false,
    ['encrypt']
  );

  // 2. 生成随机 IV
  const iv = crypto.getRandomValues(new Uint8Array(12));

  // 3. 加密
  const ciphertext = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv },
    key,
    enc.encode(plaintext)
  );

  // 4. 拼接:salt + iv + ciphertext
  return concatBuffers(salt, iv, ciphertext);
}

关键安全决策

决策 选择 理由
对称模式 AES-GCM(非 CBC) GCM 提供认证加密,防篡改
密钥派生 PBKDF2 + SHA-256 标准、广泛支持
迭代次数 600,000 OWASP 2023 推荐最低值
IV 长度 12 字节(96 位) GCM 模式推荐长度
Salt 16 字节随机 防止彩虹表攻击

国密算法:JS 实现的挑战

国密算法体系

算法 类型 对标国际 工具库实现
SM2 非对称加密/签名 ECDSA (P-256) sm-crypto
SM3 哈希 SHA-256 sm-crypto
SM4 对称加密 AES-128 sm-crypto

sm-crypto 库的使用

import { sm2, sm3, sm4 } from 'sm-crypto';

// SM2 密钥对生成
const keyPair = sm2.generateKeyPairHex();
// publicKey: keyPair.publicKey (130 hex chars, uncompressed)
// privateKey: keyPair.privateKey (64 hex chars)

// SM2 加密(C1C3C4 模式,国密标准)
const cipherMode = 1; // 1 = C1C3C4, 0 = C1C2C3
const ciphertext = sm2.doEncrypt(msg, keyPair.publicKey, cipherMode);

// SM2 解密
const plaintext = sm2.doDecrypt(ciphertext, keyPair.privateKey, cipherMode);

// SM3 哈希
const hash = sm3('message');

// SM4 加密(ECB 模式)
const key = '0123456789abcdeffedcba9876543210'; // 128-bit hex
const encrypted = sm4.encrypt(msg, key);

性能对比

操作 Web Crypto (AES-256-GCM) sm-crypto (SM4) 倍率
1MB 加密 2ms 45ms 22x
1MB 解密 2ms 42ms 21x
密钥生成 0.5ms 3ms 6x

Web Crypto API 快 20 倍以上,因为它使用浏览器原生 C/Rust 实现(或硬件加速),而 sm-crypto 是纯 JS 大数运算。

优化策略

  1. Web Worker 卸载:将 SM2/SM4 计算放入 Worker 线程,避免阻塞 UI
  2. WASM 加速:将 sm-crypto 的核心运算编译为 Wasm(社区已有实验)
  3. 数据分片:大文件分块加密,显示进度条

加密工具的架构设计

工具库加密模块的层次结构

用户界面层(React 组件)
     ↓
加密服务层(统一接口)
     ↓
┌──────────────┬──────────────┐
│ Web Crypto   │ sm-crypto    │
│ (标准算法)    │ (国密算法)    │
│ 浏览器原生    │ 纯 JS 实现   │
└──────────────┴──────────────┘

统一加密接口设计

interface CryptoService {
  encrypt(data: Uint8Array, key: CryptoKeyInput): Promise<Uint8Array>;
  decrypt(data: Uint8Array, key: CryptoKeyInput): Promise<Uint8Array>;
  generateKey(): Promise<CryptoKeyOutput>;
}

标准算法和国密算法都实现同一接口,上层组件不感知底层差异。

文件加密的内存管理

async function encryptFile(file: File, password: string) {
  // 1. 读取文件到内存
  const buffer = await file.arrayBuffer();

  // 2. 大文件分片处理(避免单次加密内存溢出)
  const CHUNK_SIZE = 64 * 1024 * 1024; // 64MB
  if (buffer.byteLength > CHUNK_SIZE) {
    return encryptFileInChunks(buffer, password, CHUNK_SIZE);
  }

  // 3. 加密
  const result = await aesGcmEncrypt(new Uint8Array(buffer), password);

  // 4. 清理敏感数据
  buffer = null; // 让 GC 回收

  return result;
}

常见加密误区

误区 1:Base64 = 加密

Base64("密码123") = "5a+G56CBMTIz"  ← 一秒还原
AES-256("密码123") = "U2FsdGVkX1..."  ← 没有密钥无法还原

Base64 是编码,不是加密。任何人都能解码。

误区 2:MD5/SHA-1 可以加密

哈希是单向函数,不能"解密"。它们用于验证完整性,不是加密。

  • MD5:已被破解,不要用于安全场景
  • SHA-1:已被碰撞攻击,不推荐
  • SHA-256/SM3:目前安全

误区 3:ECB 模式是安全的

ECB 模式:相同明文块 → 相同密文块(可识别图案)
CBC/GCM 模式:相同明文块 → 不同密文块(安全)

工具库的 AES 工具只提供 GCM 模式,不提供不安全的 ECB。


总结

浏览器端加密已经成为现实:

  • Web Crypto API:标准算法(AES/RSA/SHA)接近原生性能
  • sm-crypto:国密算法纯 JS 实现,满足合规需求
  • 零上传架构:密钥和数据不离开用户设备

工具库提供了 AES加密RSA加密SM2加密SM3哈希SM4加密 等 30+ 种加密解密工具,全部浏览器本地处理,保护你的数据安全。

本站提供浏览器本地工具,免注册即可试用 →

#加密#WebCrypto#国密#SM2#AES#安全