TypeScript 加密集成方案:crypto-js 企业级实践指南
TypeScript 加密集成方案:crypto-js 企业级实践指南
(一)一、安装与配置(TypeScript 环境)
1.1. 依赖安装
在 TypeScript 项目中,需同时安装加密库与类型声明包,确保类型安全:
npm install crypto-js @types/crypto-js # 安装核心库与类型声明
• crypto-js:提供 AES、SHA 等加密算法的实现。
• @types/crypto-js:官方类型声明包,为 crypto-js 提供完整的 TypeScript 类型支持,避免类型错误。
(二)二、基础用法(AES 加密/解密)
1.1. 简单字符串加密
import CryptoJS from 'crypto-js';
// 原始数据与密钥(密钥长度建议 16/24/32 字节,对应 AES-128/192/256)
const message = '敏感数据123';
const secretKey = 'mySecretKey12345'; // 示例密钥(实际需通过环境变量管理)
// 加密:返回 Base64 格式密文
const encrypted = CryptoJS.AES.encrypt(message, secretKey).toString();
console.log('加密结果:', encrypted); // 输出类似:U2FsdGVkX19zX...
// 解密:恢复原始文本
const bytes = CryptoJS.AES.decrypt(encrypted, secretKey);
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
console.log('解密结果:', decrypted); // 输出:敏感数据123
2.2. 对象数据加密(序列化与反序列化)
对象需先转为字符串再加密,解密后解析回对象:
// 待加密对象
const userData = { id: 'U1001', role: 'admin' };
// 加密:对象 → 字符串 → 密文
const encryptedObj = CryptoJS.AES.encrypt(
JSON.stringify(userData), // 序列化对象为字符串
secretKey
).toString();
// 解密:密文 → 字符串 → 对象
const decryptedObj = JSON.parse(
CryptoJS.AES.decrypt(encryptedObj, secretKey)
.toString(CryptoJS.enc.Utf8) // 解密为字符串
);
console.log('解密对象:', decryptedObj); // 输出:{ id: 'U1001', role: 'admin' }
(三)三、企业级安全实践(推荐)
1.1. 使用 CBC 模式 + IV 增强安全性
默认 AES 模式(ECB)对相同明文生成相同密文,易被分析。推荐使用 CBC 模式并配合随机 IV(初始化向量):
// 密钥和 IV 需转为 WordArray 格式(16 字节)
const key = CryptoJS.enc.Utf8.parse('16BytesKey_123456'); // AES-128 密钥(16 字节)
const iv = CryptoJS.enc.Utf8.parse('16BytesIV_abcdefgh'); // 固定 IV(生产环境建议动态生成)
// 加密函数
const encrypt = (data: string) => {
return CryptoJS.AES.encrypt(data, key, {
iv,
mode: CryptoJS.mode.CBC, // 使用 CBC 模式
padding: CryptoJS.pad.Pkcs7 // PKCS7 填充(前后端需一致)
}).toString();
};
// 解密函数
const decrypt = (ciphertext: string) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, key, { iv });
return bytes.toString(CryptoJS.enc.Utf8);
};
2.2. 封装为可复用服务类(工程优化)
通过类封装加解密逻辑,实现代码复用与类型安全:
// utils/crypto.ts(加密服务类)
import CryptoJS from 'crypto-js';
class CryptoService {
private key: CryptoJS.lib.WordArray;
private iv: CryptoJS.lib.WordArray;
constructor() {
// 从环境变量读取密钥(禁止硬编码)
this.key = CryptoJS.enc.Utf8.parse(import.meta.env.VITE_CRYPTO_KEY);
// 动态生成 IV(推荐每次加密生成随机 IV,需存储 IV 与密文关联)
this.iv = CryptoJS.lib.WordArray.random(16);
}
/** 加密数据(支持字符串或对象) */
encrypt(data: string | object): string {
const strData = typeof data === 'string' ? data : JSON.stringify(data);
return CryptoJS.AES.encrypt(strData, this.key, {
iv: this.iv,
mode: CryptoJS.mode.CBC
}).toString();
}
/** 解密数据(自动解析对象或返回字符串) */
decrypt<T = string>(ciphertext: string): T {
const bytes = CryptoJS.AES.decrypt(ciphertext, this.key, { iv: this.iv });
const strResult = bytes.toString(CryptoJS.enc.Utf8);
try {
return JSON.parse(strResult) as T; // 尝试解析为对象
} catch {
return strResult as T; // 解析失败则返回原始字符串
}
}
}
export default new CryptoService(); // 单例模式导出
调用示例:
// 加密对象
const encryptedUser = CryptoService.encrypt({ id: 1, name: "Alice" });
// 解密为对象(带类型推断)
const user = CryptoService.decrypt<{ id: number; name: string }>(encryptedUser);
console.log(user.name); // 输出:Alice
(四)四、关键注意事项
1.1. 密钥管理规范
• 禁止硬编码密钥:密钥需通过环境变量(如 .env 文件中的 VITE_CRYPTO_KEY)注入,避免代码提交时泄露。
• 动态 IV 生成:生产环境建议每次加密生成随机 IV(如 CryptoJS.lib.WordArray.random(16)),并将 IV 与密文关联存储(如 iv|ciphertext),避免重复 IV 导致的安全风险。
2.2. 类型安全保障
• @types/crypto-js 已提供完整类型定义,无需手动声明类型。
• 封装服务类时使用泛型 decrypt<T>(),实现解密结果的自动类型推断(如 decrypt<{ id: number }>() 直接返回指定类型对象)。
3.3. 算法选择原则
• 敏感数据:强制使用 AES-CBC 或 AES-GCM 模式(GCM 支持认证加密,更安全)。
• 避免弱算法:MD5、SHA-1 易碰撞,仅用于非敏感场景(如缓存键生成);敏感场景推荐 SHA-256 及以上哈希算法。
(五)五、替代方案(原生 Web Crypto API)
若项目仅需支持现代浏览器或 Node.js ≥ 15.4.0,可使用原生 Web Crypto API(无需安装依赖,更安全):
// 浏览器原生加密示例(AES-GCM 模式)
const encryptWithWebCrypto = async (data: string, secretKey: string) => {
const encoder = new TextEncoder();
const encodedData = encoder.encode(data); // 数据编码为 Uint8Array
// 导入密钥(需与加密算法匹配)
const key = await crypto.subtle.importKey(
'raw',
encoder.encode(secretKey), // 密钥需为 16/24/32 字节
{ name: 'AES-GCM' },
false,
['encrypt']
);
// 生成随机 IV(12 字节,AES-GCM 推荐长度)
const iv = crypto.getRandomValues(new Uint8Array(12));
// 加密数据
const encrypted = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
key,
encodedData
);
// 将 IV 与密文拼接(需存储 IV 用于解密)
const ivPlusEncrypted = new Uint8Array([...iv, ...new Uint8Array(encrypted)]);
return btoa(String.fromCharCode(...ivPlusEncrypted)); // 转为 Base64 字符串
};
(六)总结
在 TypeScript 中实现加密功能,推荐方案为:
• 标准集成:crypto-js + @types/crypto-js(兼容性强,支持多端)。
• 安全实践:强制使用 CBC/GCM 模式、动态 IV、密钥环境变量管理。
• 工程优化:封装服务类统一管理加解密逻辑,提升代码复用性和类型安全。
注意:避免使用非官方库(如 crypto-ts),防止代码漏洞或类型缺失。示例代码均通过 TypeScript 严格类型检查,可直接集成至 Vue/React/Angular 等前端框架项目。对于金融级安全需求,建议结合服务端加密与 HTTPS 传输。