Skip to content

AES加密算法实践笔记

基本概念

AES(Advanced Encryption Standard)是一种对称加密算法,被广泛应用于数据加密。主要特点:

  • 分组密码工作模式:ECB、CBC、CFB、OFB等
  • 支持128、192、256位密钥长度.
  • 加密过程包括:SubBytes、ShiftRows、MixColumns、AddRoundKey四个步骤

实际应用

在前端项目中,我们使用crypto-js库实现AES加密。以下是一个完整实现:

javascript
import CryptoJS from 'crypto-js';

/**
 * 定义加密密钥 (32位16进制数)
 * 注意:实际项目中不建议硬编码密钥
 * 建议:
 * 1. 使用环境变量存储
 * 2. 通过后端接口动态获取
 * 3. 定期更换密钥
 */
const secretKey = '';

/**
 * AES加密函数
 * @param {string|object} data - 需要加密的数据,可以是字符串或对象
 * @returns {string} - 返回base64编码的加密结果
 * 
 * 加密流程:
 * 1. 如果输入是对象,先转换为JSON字符串
 * 2. 使用Base64解码密钥
 * 3. 使用AES-ECB模式加密,填充方式为PKCS7
 * 4. 将加密结果转为Base64字符串
 * 
 * 注意事项:
 * - ECB模式虽然实现简单,但安全性较低
 * - 生产环境建议使用CBC模式
 * - 确保密钥的安全存储和传输
 */
export function encrypt(data) {
  // 如果是对象类型,转换为JSON字符串
  // 这样可以统一处理不同类型的输入数据
  const plainText = typeof data === 'object' ? JSON.stringify(data) : data;
  
  // 将密钥转换为Base64格式
  // CryptoJS要求密钥必须是Base64格式的WordArray对象
  let key = CryptoJS.enc.Base64.parse(secretKey);
  
  // 使用AES加密
  // 配置参数:
  // - mode: 使用ECB模式(Electronic Codebook)
  // - padding: 使用PKCS7填充(也叫PKCS5)
  let encrypted = CryptoJS.AES.encrypt(plainText, key, {
    mode: CryptoJS.mode.ECB,      // 使用ECB模式
    padding: CryptoJS.pad.Pkcs7   // 使用PKCS7填充
  });
  
  // 将加密结果(CipherParams对象)转换为Base64字符串
  // 这样可以安全地在网络上传输加密数据
  return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}

/**
 * AES解密函数
 * @param {string} cipherText - base64编码的密文
 * @returns {string} - 返回解密后的明文
 * 
 * 解密流程:
 * 1. 使用Base64解码密钥
 * 2. 使用AES-ECB模式解密,填充方式为PKCS7
 * 3. 将解密结果转为UTF8字符串
 * 
 * 错误处理:
 * - 如果密文格式错误,将抛出异常
 * - 如果密钥错误,将得到乱码
 * - 建议添加try-catch进行异常处理
 */
export function decrypt(cipherText) {
  // 将密钥转换为Base64格式
  // 解密时需要使用和加密时相同的密钥格式
  let key = CryptoJS.enc.Base64.parse(secretKey);
  
  // 使用AES解密,返回WordArray对象(相当于Java中的字节数组)
  // 配置需要和加密时保持一致:
  // - 相同的mode
  // - 相同的padding
  let decrypted = CryptoJS.AES.decrypt(cipherText, key, {
    mode: CryptoJS.mode.ECB,      // 使用ECB模式
    padding: CryptoJS.pad.Pkcs7   // 使用PKCS7填充
  });

  // 将解密结果转换为UTF8字符串
  // 如果解密失败,这一步可能抛出异常
  return decrypted.toString(CryptoJS.enc.Utf8);
}

关键点解析

1. 工作模式选择

  • 本例使用ECB模式(Electronic Codebook)
  • 优点:实现简单,可并行处理
  • 缺点:同样的明文块会产生相同的密文块,安全性较低
  • 实际项目中可考虑使用CBC模式提高安全性

2. 填充方式

  • 使用PKCS7填充
  • 原理:数据块不足时补充字节,补充值为缺少的字节数
  • 例如:缺少3个字节,则补充3个值为3的字节

3. 数据编码处理

  • 密钥使用Base64编码
  • 密文输出使用Base64编码
  • 确保数据在传输过程中的完整性

使用场景

  1. 敏感数据传输
javascript
// 加密用户信息
const userInfo = {
  id: 1001,
  name: 'John'
};
const encrypted = encrypt(userInfo);
  1. 接口数据加密
javascript
// API请求数据加密
async function apiRequest(data) {
  const encrypted = encrypt(data);
    const response = await fetch('/api/endpoint', {
    method: 'POST',
    body: JSON.stringify({ data: encrypted })
  });
  const result = await response.json();
  return decrypt(result.data);
}

注意事项

  1. 密钥管理
    • 不要在代码中硬编码密钥
  • 考虑使用环境变量或配置中心
  • 定期更换密钥
  1. 安全性考虑
  • ECB模式安全性较低,建议使用CBC模式
  • 添加签名机制防止数据篡改
  • 使用HTTPS传输加密数据
  1. 性能优化
  • 只加密必要的敏感数据
  • 考虑使用Web Workers处理大量数据加密
  • 实现加密数据缓存机制

面试要点

  1. AES算法的基本原理
  2. 不同工作模式的优缺点
  3. 为什么选择PKCS7填充
  4. Base64编码的作用
  5. 如何提高加密方案的安全性
  6. 前端加密的实际应用场景

扩展阅读