JavaScript系列(81)--加密技术详解
JavaScript 加密技术详解 🔐
JavaScript 加密技术在现代Web应用中扮演着重要角色,它不仅用于保护数据安全,还为我们提供了数据完整性验证和身份认证等重要功能。让我们深入了解JavaScript中的加密技术。
加密基础概述 🌟
💡 小知识:加密可以分为对称加密和非对称加密。对称加密使用相同的密钥进行加密和解密,而非对称加密使用公钥加密、私钥解密。常见的对称加密算法包括AES、DES,非对称加密算法包括RSA、ECC等。
常用加密算法实现 📊
// 1. AES 加密实现
class AESCrypto {
constructor(key) {
this.key = key;
this.algorithm = {
name: 'AES-GCM',
length: 256
};
}
async generateKey() {
return await crypto.subtle.generateKey(
this.algorithm,
true,
['encrypt', 'decrypt']
);
}
async encrypt(data) {
const iv = crypto.getRandomValues(new Uint8Array(12));
const encodedData = new TextEncoder().encode(data);
const key = await this.generateKey();
const encrypted = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv
},
key,
encodedData
);
return {
encrypted: new Uint8Array(encrypted),
iv,
key
};
}
async decrypt(encryptedData, key, iv) {
const decrypted = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv
},
key,
encryptedData
);
return new TextDecoder().decode(decrypted);
}
}
// 2. RSA 加密实现
class RSACrypto {
constructor() {
this.algorithm = {
name: 'RSA-OAEP',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256'
};
}
async generateKeyPair() {
return await crypto.subtle.generateKey(
this.algorithm,
true,
['encrypt', 'decrypt']
);
}
async encrypt(data, publicKey) {
const encodedData = new TextEncoder().encode(data);
return await crypto.subtle.encrypt(
{
name: 'RSA-OAEP'
},
publicKey,
encodedData
);
}
async decrypt(encryptedData, privateKey) {
const decrypted = await crypto.subtle.decrypt(
{
name: 'RSA-OAEP'
},
privateKey,
encryptedData
);
return new TextDecoder().decode(decrypted);
}
}
// 3. 哈希函数实现
class HashGenerator {
static async sha256(data) {
const encodedData = new TextEncoder().encode(data);
const hashBuffer = await crypto.subtle.digest('SHA-256', encodedData);
return Array.from(new Uint8Array(hashBuffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
static async hmac(key, data) {
const cryptoKey = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(key),
{
name: 'HMAC',
hash: 'SHA-256'
},
false,
['sign', 'verify']
);
const signature = await crypto.subtle.sign(
'HMAC',
cryptoKey,
new TextEncoder().encode(data)
);
return Array.from(new Uint8Array(signature))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
}
密钥管理 🔑
// 1. 密钥生成与存储
class KeyManager {
constructor() {
this.storage = new SecureStorage();
}
async generateEncryptionKey() {
const key = await crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 256
},
true,
['encrypt', 'decrypt']
);
const exportedKey = await crypto.subtle.exportKey('raw', key);
const keyString = this.arrayBufferToBase64(exportedKey);
await this.storage.setItem('encryption_key', keyString);
return key;
}
async getStoredKey() {
const keyString = await this.storage.getItem('encryption_key');
if (!keyString) return null;
const keyData = this.base64ToArrayBuffer(keyString);
return await crypto.subtle.importKey(
'raw',
keyData,
{
name: 'AES-GCM',
length: 256
},
true,
['encrypt', 'decrypt']
);
}
arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
return btoa(String.fromCharCode.apply(null, bytes));
}
base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
}
// 2. 密钥派生
class KeyDerivation {
static async deriveKey(password, salt) {
const encoder = new TextEncoder();
const passwordData = encoder.encode(password);
const saltData = encoder.encode(salt);
const importedKey = await crypto.subtle.importKey(
'raw',
passwordData,
'PBKDF2',
false,
['deriveBits', 'deriveKey']
);
return await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: saltData,
iterations: 100000,
hash: 'SHA-256'
},
importedKey,
{
name: 'AES-GCM',
length: 256
},
true,
['encrypt', 'decrypt']
);
}
}
// 3. 密钥轮换
class KeyRotation {
constructor(storage) {
this.storage = storage;
this.currentKeyVersion = 1;
}
async rotateKey() {
// 生成新密钥
const newKey = await crypto.subtle.generateKey(
{
name: 'AES-GCM',
length: 256
},
true,
['encrypt', 'decrypt']
);
// 获取旧密钥
const oldKey = await this.getCurrentKey();
// 重新加密所有数据
await this.reencryptData(oldKey, newKey);
// 更新密钥版本
this.currentKeyVersion++;
await this.storage.setItem('key_version', this.currentKeyVersion);
// 存储新密钥
await this.storeKey(newKey);
}
async reencryptData(oldKey, newKey) {
// 实现数据重新加密的逻辑
}
}
安全通信实现 🌐
// 1. 安全数据传输
class SecureTransport {
constructor() {
this.rsaCrypto = new RSACrypto();
this.aesCrypto = new AESCrypto();
}
async establishSecureChannel() {
// 生成临时会话密钥
const sessionKey = await this.aesCrypto.generateKey();
// 使用RSA加密会话密钥
const encryptedSessionKey = await this.rsaCrypto.encrypt(
sessionKey,
this.serverPublicKey
);
// 发送加密的会话密钥
await this.sendToServer(encryptedSessionKey);
return sessionKey;
}
async sendSecureData(data, sessionKey) {
// 加密数据
const encrypted = await this.aesCrypto.encrypt(data, sessionKey);
// 生成消息认证码
const mac = await HashGenerator.hmac(sessionKey, encrypted);
// 发送加密数据和MAC
return {
data: encrypted,
mac
};
}
}
// 2. 安全WebSocket
class SecureWebSocket {
constructor(url) {
this.url = url;
this.ws = null;
this.sessionKey = null;
}
async connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = async () => {
// 建立安全通道
this.sessionKey = await this.establishSecureChannel();
};
this.ws.onmessage = async event => {
const decrypted = await this.decryptMessage(event.data);
this.handleMessage(decrypted);
};
}
async sendSecureMessage(message) {
if (!this.sessionKey) {
throw new Error('Secure channel not established');
}
const encrypted = await this.aesCrypto.encrypt(
message,
this.sessionKey
);
this.ws.send(encrypted);
}
}
// 3. 端到端加密
class E2EEncryption {
constructor() {
this.keyPair = null;
this.peerPublicKeys = new Map();
}
async initialize() {
// 生成密钥对
this.keyPair = await this.rsaCrypto.generateKeyPair();
// 发布公钥
await this.publishPublicKey(this.keyPair.publicKey);
}
async sendSecureMessage(peerId, message) {
const peerPublicKey = this.peerPublicKeys.get(peerId);
if (!peerPublicKey) {
throw new Error('Peer public key not found');
}
// 生成一次性会话密钥
const sessionKey = await this.aesCrypto.generateKey();
// 使用对方公钥加密会话密钥
const encryptedSessionKey = await this.rsaCrypto.encrypt(
sessionKey,
peerPublicKey
);
// 使用会话密钥加密消息
const encryptedMessage = await this.aesCrypto.encrypt(
message,
sessionKey
);
return {
key: encryptedSessionKey,
message: encryptedMessage
};
}
}
实战应用示例 💼
// 1. 安全存储系统
class SecureStorage {
constructor() {
this.crypto = new AESCrypto();
this.keyManager = new KeyManager();
}
async setItem(key, value) {
const encryptionKey = await this.keyManager.getStoredKey();
const encrypted = await this.crypto.encrypt(
JSON.stringify(value),
encryptionKey
);
localStorage.setItem(
key,
JSON.stringify({
data: Array.from(encrypted.encrypted),
iv: Array.from(encrypted.iv)
})
);
}
async getItem(key) {
const stored = localStorage.getItem(key);
if (!stored) return null;
const { data, iv } = JSON.parse(stored);
const encryptionKey = await this.keyManager.getStoredKey();
const decrypted = await this.crypto.decrypt(
new Uint8Array(data),
encryptionKey,
new Uint8Array(iv)
);
return JSON.parse(decrypted);
}
}
// 2. 安全表单提交
class SecureForm {
constructor(formElement) {
this.form = formElement;
this.rsaCrypto = new RSACrypto();
}
async initialize() {
// 获取服务器公钥
this.serverPublicKey = await this.fetchServerPublicKey();
this.form.addEventListener('submit', this.handleSubmit.bind(this));
}
async handleSubmit(event) {
event.preventDefault();
const formData = new FormData(this.form);
const sensitiveData = Object.fromEntries(formData.entries());
// 加密敏感数据
const encrypted = await this.rsaCrypto.encrypt(
JSON.stringify(sensitiveData),
this.serverPublicKey
);
// 发送加密数据
await fetch('/api/submit', {
method: 'POST',
body: encrypted
});
}
}
// 3. 密码管理器
class PasswordManager {
constructor() {
this.storage = new SecureStorage();
this.crypto = new AESCrypto();
}
async addPassword(site, username, password) {
const entry = {
site,
username,
password,
created: Date.now()
};
await this.storage.setItem(
`pwd_${site}`,
entry
);
}
async getPassword(site) {
return await this.storage.getItem(`pwd_${site}`);
}
async generateSecurePassword(length = 16) {
const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()';
const array = new Uint8Array(length);
crypto.getRandomValues(array);
let password = '';
for (let i = 0; i < length; i++) {
password += charset[array[i] % charset.length];
}
return password;
}
}
安全最佳实践 🛡️
// 1. 安全检查工具
class SecurityChecker {
static checkEnvironment() {
// 检查HTTPS
if (location.protocol !== 'https:') {
console.warn('Not running on HTTPS');
return false;
}
// 检查Web Crypto API
if (!crypto.subtle) {
console.error('Web Crypto API not available');
return false;
}
return true;
}
static validateInput(input) {
// 移除危险字符
return input.replace(/[<>'"]/g, '');
}
static checkPasswordStrength(password) {
const checks = {
length: password.length >= 12,
uppercase: /[A-Z]/.test(password),
lowercase: /[a-z]/.test(password),
numbers: /[0-9]/.test(password),
special: /[!@#$%^&*]/.test(password)
};
return Object.values(checks).filter(Boolean).length;
}
}
// 2. 安全配置管理
class SecurityConfig {
static getDefaultConfig() {
return {
keySize: 256,
iterations: 100000,
saltSize: 16,
ivSize: 12,
tagSize: 128,
minPasswordLength: 12,
sessionTimeout: 3600000 // 1小时
};
}
static validateConfig(config) {
const defaults = this.getDefaultConfig();
// 确保配置值不低于最小安全要求
return {
...defaults,
...config,
keySize: Math.max(config.keySize, defaults.keySize),
iterations: Math.max(config.iterations, defaults.iterations),
minPasswordLength: Math.max(
config.minPasswordLength,
defaults.minPasswordLength
)
};
}
}
// 3. 错误处理
class CryptoError extends Error {
constructor(message, code) {
super(message);
this.name = 'CryptoError';
this.code = code;
}
static handleError(error) {
if (error instanceof CryptoError) {
console.error(`Crypto error ${error.code}: ${error.message}`);
} else {
console.error('Unexpected error:', error);
}
// 安全地清理敏感数据
this.cleanupSensitiveData();
}
static cleanupSensitiveData() {
// 实现安全清理逻辑
}
}
结语 📝
JavaScript加密技术为我们提供了保护数据安全的重要工具。我们学习了:
- 常用加密算法的实现
- 密钥管理和派生
- 安全通信的实现
- 实战应用场景
- 安全最佳实践
- 错误处理和调试
💡 学习建议:
- 深入理解加密算法的原理
- 注意密钥的安全管理
- 遵循安全最佳实践
- 定期更新加密方案
- 做好异常处理和日志记录
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻