正在加载,请稍候…

在线文本加密:AES、DES 与对称加密详解

使用 AES、DES 等算法对文本进行加密和解密。了解对称加密的工作原理及其适用场景。

在线文本加密:AES、DES 与对称加密详解

对称加密与非对称加密

对称加密使用相同的密钥对数据进行加密和解密。它速度快、效率高,非常适合加密大量数据。其挑战在于密钥分发——双方在通信前需要安全地共享密钥。

非对称加密(如 RSA)使用公钥/私钥对。它解决了密钥分发问题,但速度慢得多。实践中,大多数系统两者兼用:非对称加密用于安全交换对称密钥,然后对称加密用于实际数据传输。HTTPS 正是这样工作的。

在线文本加密:AES、DES 与对称加密详解 插图

AES 算法

AES(高级加密标准)是世界上最广泛使用的对称密码,由 NIST 于 2001 年标准化。它取代了 DES 和 3DES,并用于几乎所有现代安全协议——TLS、磁盘加密、VPN 等。

AES 对 128 位数据块(每次 16 字节)进行操作,使用 128、192 或 256 位的密钥。它应用多轮替换、置换和混合变换。

AES 密钥长度

变体 密钥长度 轮数 安全性
AES-128 128 位(16 字节) 10 ✅ 安全
AES-192 192 位(24 字节) 12 ✅ 安全
AES-256 256 位(32 字节) 14 ✅ 推荐

AES-128 和 AES-256 在安全性上没有实际差异——两者在当前和可预见的未来技术下都能抵御暴力破解攻击。AES-256 提供了针对量子计算机(理论上通过 Grover 算法将有效密钥长度减半)的安全余量。

分组密码模式

像 AES 这样的分组密码一次只能加密恰好一个 128 位数据块。操作模式定义了如何将分组密码应用于任意长度的数据。

在线文本加密:AES、DES 与对称加密详解 插图

ECB(电子密码本)——切勿使用

每个数据块独立加密。相同的明文块产生相同的密文块。这会暴露结构化数据中的模式(经典例子是加密图像——形状仍然可见)。

CBC(密码分组链接)

每个数据块在加密前与前一个密文块进行 XOR 运算。第一个块需要随机的初始化向量(IV)。IV 每次加密必须唯一,但无需保密。

C₀ = IV
Cᵢ = Encrypt(K, Pᵢ ⊕ Cᵢ₋₁)

适合文件加密。需要填充以处理非块大小的数据。

GCM(伽罗瓦/计数器模式)——推荐

将计数器模式(流密码)与伽罗瓦消息认证码(GMAC)结合。提供认证加密:输出包含一个认证标签,可检测任何篡改。

AES-256-GCM 是对称加密的黄金标准——TLS 1.3 在 HTTPS 中使用它。

在线文本加密:AES、DES 与对称加密详解 插图

CTR(计数器模式)

加密连续的计数器值并与明文进行 XOR 运算。可并行化,无需填充。无认证。

算法比较

算法 状态 密钥长度 安全性
DES 🔴 已破解 56 位 1999 年被破解
3DES 🟡 已弃用 112/168 位 慢,正在退役
AES-128 ✅ 安全 128 位 标准
AES-256 ✅ 推荐 256 位 抗量子余量
ChaCha20 ✅ 现代 256 位 移动/嵌入式设备上快

3DES(三重 DES)用于遗留系统——新开发应避免使用。AES 已完全取代它。

从密码派生密钥

当使用密码而非随机密钥进行加密时,必须使用**密钥派生函数(KDF)**将密码转换为合适的加密密钥。切勿直接将密码用作 AES 密钥。

// 使用 PBKDF2 从密码派生密钥
const key = await crypto.subtle.importKey(...);
const derivedKey = await crypto.subtle.deriveKey(
  { name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' },
  key, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']
);

常见 KDF:PBKDF2、scrypt、Argon2。使用高迭代次数(PBKDF2 至少 100,000 次)以减缓暴力破解攻击。

实际加密示例

// Web Crypto API(浏览器)
async function encryptText(plaintext, password) {
  const encoder = new TextEncoder();
  const data = encoder.encode(plaintext);
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12));

  const keyMaterial = await crypto.subtle.importKey(
    'raw', encoder.encode(password), 'PBKDF2', false, ['deriveKey']
  );
  const key = await crypto.subtle.deriveKey(
    { name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' },
    keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['encrypt']
  );

  const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data);
  return { encrypted, salt, iv };
}

→ 尝试 加密工具