eagleye

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 传输。

posted on 2025-06-20 10:44  GoGrid  阅读(305)  评论(0)    收藏  举报

导航