React Router
Cryptography

对称加密

深入理解对称加密的原理、算法和应用

对称加密

对称加密是最古老也是最常用的加密方式,它使用相同的密钥进行加密和解密操作。

对称加密的基本原理

对称加密的核心思想是:发送方和接收方共享同一个密钥

明文 + 密钥 = 密文
密文 + 密钥 = 明文

工作流程

  1. 密钥生成:生成一个随机密钥
  2. 密钥分发:将密钥安全地分发给通信双方
  3. 加密过程:使用密钥对明文进行加密
  4. 传输密文:将密文传输给接收方
  5. 解密过程:使用相同密钥对密文进行解密

经典对称加密算法

1. 凯撒密码(Caesar Cipher)

最简单的替换密码,将每个字母向后移动固定位数。

// 凯撒密码实现
function caesarEncrypt(text, shift) {
  return text.split('').map(char => {
    if (char >= 'A' && char <= 'Z') {
      return String.fromCharCode((char.charCodeAt(0) - 65 + shift) % 26 + 65);
    }
    if (char >= 'a' && char <= 'z') {
      return String.fromCharCode((char.charCodeAt(0) - 97 + shift) % 26 + 97);
    }
    return char;
  }).join('');
}

function caesarDecrypt(text, shift) {
  return caesarEncrypt(text, 26 - shift);
}

// 示例
const plaintext = "HELLO WORLD";
const key = 3;
const ciphertext = caesarEncrypt(plaintext, key);
console.log(`明文: ${plaintext}`);
console.log(`密文: ${ciphertext}`);
console.log(`解密: ${caesarDecrypt(ciphertext, key)}`);

2. 维吉尼亚密码(Vigenère Cipher)

使用关键词进行多表替换,比凯撒密码更安全。

// 维吉尼亚密码实现
function vigenereEncrypt(text, keyword) {
  const key = keyword.toUpperCase().repeat(Math.ceil(text.length / keyword.length));
  return text.split('').map((char, index) => {
    if (char >= 'A' && char <= 'Z') {
      const shift = key.charCodeAt(index) - 65;
      return String.fromCharCode((char.charCodeAt(0) - 65 + shift) % 26 + 65);
    }
    if (char >= 'a' && char <= 'z') {
      const shift = key.charCodeAt(index) - 65;
      return String.fromCharCode((char.charCodeAt(0) - 97 + shift) % 26 + 97);
    }
    return char;
  }).join('');
}

现代对称加密算法

1. DES(Data Encryption Standard)

  • 密钥长度:56位
  • 分组长度:64位
  • 轮数:16轮
  • 状态:已不推荐使用

2. 3DES(Triple DES)

  • 密钥长度:168位(3个56位密钥)
  • 分组长度:64位
  • 安全性:中等
  • 状态:逐渐被AES替代

3. AES(Advanced Encryption Standard)

AES 特点

  • 密钥长度:128位、192位、256位
  • 分组长度:128位
  • 轮数:10轮(128位)、12轮(192位)、14轮(256位)
  • 安全性:极高,被广泛采用

AES 加密过程

// AES 加密示例(使用 Node.js crypto 模块)
const crypto = require('crypto');

function aesEncrypt(text, key) {
  const cipher = crypto.createCipher('aes-256-cbc', key);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

function aesDecrypt(encryptedText, key) {
  const decipher = crypto.createDecipher('aes-256-cbc', key);
  let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

// 示例
const text = "Hello, AES encryption!";
const key = "my-secret-key-32-chars-long!";
const encrypted = aesEncrypt(text, key);
const decrypted = aesDecrypt(encrypted, key);

console.log(`原文: ${text}`);
console.log(`加密: ${encrypted}`);
console.log(`解密: ${decrypted}`);

对称加密的工作模式

1. ECB(Electronic Codebook)

最简单的模式,每个分组独立加密。

// ECB 模式示例
function ecbEncrypt(plaintext, key) {
  const blockSize = 16; // AES 分组大小
  const blocks = [];
  
  // 分块
  for (let i = 0; i < plaintext.length; i += blockSize) {
    blocks.push(plaintext.slice(i, i + blockSize));
  }
  
  // 每个块独立加密
  return blocks.map(block => encryptBlock(block, key)).join('');
}

缺点:相同的明文块产生相同的密文块,容易被攻击。

2. CBC(Cipher Block Chaining)

每个明文块与前一个密文块进行XOR操作。

// CBC 模式示例
function cbcEncrypt(plaintext, key, iv) {
  const blockSize = 16;
  const blocks = [];
  let previousCipher = iv;
  
  // 分块
  for (let i = 0; i < plaintext.length; i += blockSize) {
    blocks.push(plaintext.slice(i, i + blockSize));
  }
  
  // CBC 加密
  return blocks.map(block => {
    const xored = xor(block, previousCipher);
    const encrypted = encryptBlock(xored, key);
    previousCipher = encrypted;
    return encrypted;
  }).join('');
}

优点:相同的明文块产生不同的密文块,更安全。

3. CTR(Counter)

使用计数器生成密钥流,与明文进行XOR操作。

// CTR 模式示例
function ctrEncrypt(plaintext, key, nonce) {
  const blockSize = 16;
  const blocks = [];
  
  // 分块
  for (let i = 0; i < plaintext.length; i += blockSize) {
    blocks.push(plaintext.slice(i, i + blockSize));
  }
  
  // CTR 加密
  return blocks.map((block, index) => {
    const counter = nonce + index;
    const keyStream = encryptBlock(counter, key);
    return xor(block, keyStream);
  }).join('');
}

优点:可以并行处理,适合流数据。

对称加密的优势

1. 性能优势

  • 速度快:计算复杂度低
  • 效率高:适合大量数据加密
  • 资源消耗少:CPU和内存占用小

2. 实现简单

  • 算法简单:易于理解和实现
  • 标准化好:有成熟的标准和库
  • 兼容性强:各种平台都支持

对称加密的挑战

1. 密钥管理问题

密钥分发:如何安全地将密钥分发给通信双方?

// 密钥分发示例(简化版)
function generateKey() {
  return crypto.randomBytes(32); // 生成256位密钥
}

function distributeKey(key, recipient) {
  // 这里需要安全通道来分发密钥
  // 实际应用中通常使用非对称加密来保护密钥分发
  return encryptWithPublicKey(key, recipient.publicKey);
}

2. 密钥数量问题

密钥爆炸:n个用户需要 n(n-1)/2 个密钥。

// 计算所需密钥数量
function calculateKeyCount(userCount) {
  return (userCount * (userCount - 1)) / 2;
}

console.log(`10个用户需要 ${calculateKeyCount(10)} 个密钥`);
console.log(`100个用户需要 ${calculateKeyCount(100)} 个密钥`);
console.log(`1000个用户需要 ${calculateKeyCount(1000)} 个密钥`);

3. 密钥更新问题

密钥轮换:定期更换密钥以保持安全性。

// 密钥轮换策略
class KeyManager {
  constructor() {
    this.currentKey = null;
    this.previousKey = null;
    this.keyExpiry = null;
  }
  
  rotateKey() {
    this.previousKey = this.currentKey;
    this.currentKey = generateKey();
    this.keyExpiry = Date.now() + 30 * 24 * 60 * 60 * 1000; // 30天
  }
  
  getActiveKey() {
    if (Date.now() > this.keyExpiry) {
      this.rotateKey();
    }
    return this.currentKey;
  }
}

实际应用场景

1. 文件加密

// 文件加密示例
const fs = require('fs');

function encryptFile(inputPath, outputPath, key) {
  const data = fs.readFileSync(inputPath);
  const encrypted = aesEncrypt(data.toString('base64'), key);
  fs.writeFileSync(outputPath, encrypted);
}

function decryptFile(inputPath, outputPath, key) {
  const encrypted = fs.readFileSync(inputPath, 'utf8');
  const decrypted = aesDecrypt(encrypted, key);
  const data = Buffer.from(decrypted, 'base64');
  fs.writeFileSync(outputPath, data);
}

2. 数据库加密

// 数据库字段加密
function encryptField(value, key) {
  return aesEncrypt(JSON.stringify(value), key);
}

function decryptField(encryptedValue, key) {
  const decrypted = aesDecrypt(encryptedValue, key);
  return JSON.parse(decrypted);
}

3. 通信加密

// 安全通信示例
class SecureChannel {
  constructor(sharedKey) {
    this.key = sharedKey;
  }
  
  send(message) {
    const encrypted = aesEncrypt(message, this.key);
    return {
      data: encrypted,
      timestamp: Date.now(),
      checksum: this.calculateChecksum(encrypted)
    };
  }
  
  receive(packet) {
    if (this.verifyChecksum(packet.data, packet.checksum)) {
      return aesDecrypt(packet.data, this.key);
    }
    throw new Error('数据完整性验证失败');
  }
}

最佳实践

  1. 使用强密钥:至少128位,推荐256位
  2. 选择安全模式:避免ECB,推荐CBC或CTR
  3. 使用随机IV:每次加密使用不同的初始化向量
  4. 定期轮换密钥:根据安全要求定期更换密钥
  5. 保护密钥存储:使用硬件安全模块(HSM)存储密钥
  6. 验证实现:使用经过验证的加密库

对称加密是现代密码学的基础,理解其原理和应用对于构建安全的系统至关重要。