瀏覽器端加密實戰: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 大數運算。
最佳化策略
- Web Worker 卸載:將 SM2/SM4 計算放入 Worker 執行緒,避免阻塞 UI
- WASM 加速:將 sm-crypto 的核心運算編譯為 Wasm(社群已有實驗)
- 資料分片:大檔案分塊加密,顯示進度條
加密工具的架構設計
工具庫加密模組的層次結構
使用者介面層(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#安全