以下是前端开发中常用的加密方式及其适用场景的详细说明:
加密类型 | 常用算法 | 特点 | 适用场景 |
---|---|---|---|
对称加密 | AES、DES、3DES | 加密解密使用相同密钥,速度快 | 本地存储加密、HTTP Body加密 |
非对称加密 | RSA、ECC | 公钥加密私钥解密,安全性高 | 传输敏感数据、数字签名 |
哈希算法 | SHA-256、MD5(不推荐) | 单向不可逆,验证数据完整性 | 密码存储、数据校验 |
消息认证码 | HMAC | 带密钥的哈希,防篡改 | API签名验证、防重放攻击 |
编码方案 | Base64、URL Encoding | 数据编码(非加密) | 二进制数据传输、简单混淆 |
// 使用 crypto-js 库
import CryptoJS from 'crypto-js'
// 加密
const encryptAES = (text, secretKey) => {
return CryptoJS.AES.encrypt(text, secretKey).toString()
}
// 解密
const decryptAES = (ciphertext, secretKey) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, secretKey)
return bytes.toString(CryptoJS.enc.Utf8)
}
// 使用示例
const key = 'my-secret-key-123'
const encrypted = encryptAES('敏感数据', key) // U2FsdGVkX1+Z6Jw7j6/4w6...
const decrypted = decryptAES(encrypted, key) // 敏感数据
// 使用 jsencrypt 库
import JSEncrypt from 'jsencrypt'
// 加密
const encryptRSA = (text, publicKey) => {
const encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey)
return encryptor.encrypt(text)
}
// 解密(需私钥,通常后端处理)
const privateKey = '-----BEGIN RSA PRIVATE KEY-----...'
const decryptRSA = (ciphertext) => {
const decryptor = new JSEncrypt()
decryptor.setPrivateKey(privateKey)
return decryptor.decrypt(ciphertext)
}
// 使用示例
const publicKey = '-----BEGIN PUBLIC KEY-----...'
const encrypted = encryptRSA('信用卡号', publicKey) // aGVsbG8xMjPCow==...
// 密码存储方案
const hashPassword = (password, salt) => {
return CryptoJS.SHA256(password + salt).toString()
}
// 注册时存储
const userPassword = '123456'
const salt = CryptoJS.lib.WordArray.random(16).toString() // 随机盐值
const hashedPwd = hashPassword(userPassword, salt) // 存储 hash + salt
// 登录验证
const isMatch = hashPassword(inputPwd, salt) === storedHash
// AES-GCM 加密(更安全)
async function encryptData(plaintext, key) {
const iv = crypto.getRandomValues(new Uint8Array(12))
const algorithm = { name: 'AES-GCM', iv }
const cryptoKey = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(key),
{ name: 'AES-GCM' },
false,
['encrypt']
)
const ciphertext = await crypto.subtle.encrypt(
algorithm,
cryptoKey,
new TextEncoder().encode(plaintext)
)
return { iv, ciphertext }
}
// 生成 Token
const header = { alg: 'HS256', typ: 'JWT' }
const payload = { userId: 123, exp: Date.now() + 3600 }
const secret = 'your-secret-key'
const token = [
base64(JSON.stringify(header)),
base64(JSON.stringify(payload)),
HMACSHA256(header + payload, secret)
].join('.')
密钥管理规范
// 错误方式(硬编码密钥)
const key = 'static-key' // ❌
// 正确方式(动态获取)
async function getKey() {
return fetch('/api/get-encrypt-key') // ✅
}
防御彩虹表攻击
// 密码哈希加强方案
const hash = (pwd) => {
const salt = CryptoJS.lib.WordArray.random(128/8)
const iterations = 10000 // 迭代次数
return CryptoJS.PBKDF2(pwd, salt, {
keySize: 256/32,
iterations
})
}
传输层安全
# 强制HTTPS(Nginx配置)
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
场景 | 推荐方案 | 注意事项 |
---|---|---|
用户密码存储 | PBKDF2 / bcrypt | 必须加盐、高迭代次数 |
HTTP 敏感数据传输 | HTTPS + AES(CBC/GCM) | 配合密钥轮换策略 |
防篡改参数 | HMAC-SHA256 | 签名密钥不出前端 |
临时数据保护 | Web Crypto API | 优先使用浏览器原生方案 |
简单混淆 | Base64 + 自定义规则 | 不能用于安全敏感场景 |
前端加密无法替代 HTTPS
MD5 已不安全
# 破解示例(仅需数秒)
md5("hello") = 5d41402abc4b2a76b9719d911017c592
# 可通过彩虹表快速反查
加密 ≠ 授权
Web Worker 处理加密
// 主线程
const worker = new Worker('crypto-worker.js')
worker.postMessage({ type: 'encrypt', data: 'xxx' })
// Worker线程
self.onmessage = (e) => {
const result = encryptData(e.data)
self.postMessage(result)
}
缓存加密结果
const cache = new Map()
function cachedEncrypt(data) {
if (cache.has(data)) return cache.get(data)
const result = encrypt(data)
cache.set(data, result)
return result
}
通过合理使用这些加密方案,可以在以下方面提升安全性:
但需注意:前端加密不能替代后端安全措施,敏感操作(如支付验证)仍需服务端二次验证。建议结合安全审计工具(如 OWASP ZAP)定期检测系统漏洞。