一、分类概览
1. 按加密强度分类
弱加密(编码/混淆):Base64、URL编码、简单替换
对称加密:AES、DES
非对称加密:RSA、ECC
哈希算法:MD5、SHA系列
混合加密:HTTPS、JWE
2. 按用途分类
传输加密:TLS/SSL、混合加密
存储加密:对称加密、哈希加盐
认证加密:JWT、数字签名
二、详细方法与对比分析
1. 编码类(弱保护)
// 编码
function base64Encode(str) {
return btoa(unescape(encodeURIComponent(str)));
}
// 解码
function base64Decode(encodedStr) {
return decodeURIComponent(escape(atob(encodedStr)));
}
// 使用示例
const original = "敏感数据123";
const encoded = base64Encode(original); // "5oOz5p2l5pWw5o2uMTIz"
const decoded = base64Decode(encoded); // "敏感数据123"
URL编码
// 编码
const urlEncode = encodeURIComponent("用户数据?key=value"); // "%E7%94%A8%E6%88%B7%E6%95%B0%E6%8D%AE%3Fkey%3Dvalue"
// 解码
const urlDecode = decodeURIComponent("%E7%94%A8%E6%88%B7%E6%95%B0%E6%8D%AE");
特点:不是真正的加密,仅用于数据格式转换,无安全性
2. 哈希算法
SHA-256(使用Web Crypto API)
async function sha256Hash(message) {
// 将字符串转换为Uint8Array
const encoder = new TextEncoder();
const data = encoder.encode(message);
// 计算哈希
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
// 转换为十六进制字符串
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// 使用示例
sha256Hash('password123').then(hash => {
console.log('SHA-256哈希:', hash);
});
加盐哈希(用于密码存储)
async function saltedHash(password, salt) {
const encoder = new TextEncoder();
const passwordBuffer = encoder.encode(password + salt);
const hashBuffer = await crypto.subtle.digest('SHA-256', passwordBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// 使用示例
const salt = crypto.getRandomValues(new Uint8Array(16));
saltedHash('userPassword', salt).then(hashedPassword => {
console.log('加盐哈希:', hashedPassword);
});
3. 对称加密
AES-GCM(推荐)
async function aesEncrypt(plaintext, password) {
// 生成密钥
const encoder = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey(
'raw',
encoder.encode(password),
{ name: 'PBKDF2' },
false,
['deriveKey']
);
// 派生密钥
const key = await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: crypto.getRandomValues(new Uint8Array(16)),
iterations: 100000,
hash: 'SHA-256'
},
keyMaterial,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
// 加密
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
key,
encoder.encode(plaintext)
);
return {
iv: Array.from(iv),
encrypted: Array.from(new Uint8Array(encrypted))
};
}
async function aesDecrypt(encryptedData, password) {
// 类似加密过程,使用decrypt方法
// 具体实现略
}
4. 非对称加密
RSA加密
async function generateRSAKeys() {
return await crypto.subtle.generateKey(
{
name: 'RSA-OAEP',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256'
},
true,
['encrypt', 'decrypt']
);
}
async function rsaEncrypt(publicKey, plaintext) {
const encoder = new TextEncoder();
const data = encoder.encode(plaintext);
return await crypto.subtle.encrypt(
{ name: 'RSA-OAEP' },
publicKey,
data
);
}
// 使用示例
generateRSAKeys().then(async keys => {
const encrypted = await rsaEncrypt(keys.publicKey, '敏感数据');
console.log('RSA加密结果:', new Uint8Array(encrypted));
});
5. 混合加密实践
前端数据加密传输
class SecureDataTransmitter {
constructor(serverPublicKey) {
this.serverPublicKey = serverPublicKey;
this.sessionKey = null;
}
async initSession() {
// 生成会话密钥
this.sessionKey = await crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
// 用服务器公钥加密会话密钥
const exportedKey = await crypto.subtle.exportKey('raw', this.sessionKey);
const encryptedSessionKey = await crypto.subtle.encrypt(
{ name: 'RSA-OAEP' },
this.serverPublicKey,
exportedKey
);
return encryptedSessionKey;
}
async encryptData(data) {
const encoder = new TextEncoder();
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
this.sessionKey,
encoder.encode(JSON.stringify(data))
);
return {
iv: Array.from(iv),
data: Array.from(new Uint8Array(encrypted))
};
}
}
6. 实用库封装
使用crypto-js库
// 安装: npm install crypto-js
import CryptoJS from 'crypto-js';
// AES加密
const encryptAES = (data, secretKey) => {
return CryptoJS.AES.encrypt(JSON.stringify(data), secretKey).toString();
};
// AES解密
const decryptAES = (ciphertext, secretKey) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, secretKey);
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
};
// 使用示例
const data = { userId: 123, name: '张三' };
const key = 'my-secret-key-123';
const encrypted = encryptAES(data, key);
const decrypted = decryptAES(encrypted, key);
三、对比分析表
四、选择建议
密码存储:使用加盐哈希(如bcrypt、PBKDF2)
数据传输:
简单场景:HTTPS + Base64编码
高安全场景:HTTPS + 客户端加密(AES/RSA混合)
本地存储:AES加密敏感数据
API安全:JWT签名 + HTTPS
文件加密:AES-CTR或AES-GCM模式
五、安全注意事项
永远不要在前端存储加密密钥
使用HTTPS作为基础传输层
定期更新加密算法和密钥
实施完整的密钥生命周期管理
进行安全审计和渗透测试
遵循最小权限原则
// 安全实践示例
class SecureStorage {
constructor() {
this.key = this.getKeyFromSecureSource();
}
async setItem(key, value) {
const encrypted = await aesEncrypt(value, this.key);
localStorage.setItem(key, JSON.stringify(encrypted));
}
async getItem(key) {
const encrypted = JSON.parse(localStorage.getItem(key));
return await aesDecrypt(encrypted, this.key);
}
getKeyFromSecureSource() {
// 从安全来源获取密钥,如服务器下发或用户输入
// 不要硬编码在代码中
}
}
前端加密只是安全链条中的一环,必须与后端安全措施、网络传输安全、安全开发流程等结合,才能构建完整的安全体系。