AES 加密工具 — GCM、CBC 与 CTR 模式
免费在线 AES 加密工具 — 支持 AES-128/192/256、GCM/CBC/CTR 模式,可用口令(PBKDF2)或原始密钥。100% 浏览器本地运行,不上传任何数据。
高级选项
绝不要对同一密钥重复使用 IV。留空则会生成一个安全的随机 IV。
什么是 AES 加密?
AES(高级加密标准)是一种对称分组密码,由 NIST 于 2001 年在 FIPS 197 中标准化,基于 Joan Daemen 和 Vincent Rijmen 设计的 Rijndael 算法。它以固定的 128 位分组加密数据,使用 128、192 或 256 位密钥,同一个密钥既能加密也能解密。它是现代密码学的主力,从 HTTPS 流量到磁盘加密,几乎无处不在。
原始分组密码一次只能打乱一个 16 字节的分组,因此 AES 总是运行在把各分组串联起来的工作模式之内。本工具提供三种模式,均由浏览器的 Web Crypto API 原生支持:GCM、CBC 和 CTR。GCM(Galois/Counter 模式,NIST SP 800-38D)是推荐的默认选项,因为它带有认证 —— 它会在密文旁生成一个 128 位认证标签,因此任何篡改都会在解密时被发现。CBC 和 CTR 只提供机密性;它们本身无法告诉你密文是否被改动过,这也是 TLS 1.3(RFC 8446)放弃所有 CBC 密码套件、转而使用 GCM 这类认证模式的原因。
你会注意到这里没有 ECB 模式,这是刻意为之。ECB 会把每个相同的明文分组加密成相同的密文分组,因此大范围的结构会直接泄露出来 —— 著名的「ECB 企鹅」图像在加密后依然清晰可见是一只企鹅。Web Crypto API 正是出于这个原因省略了 ECB(它只实现了 AES-CBC、AES-CTR 和 AES-GCM),我们也是如此。如果你需要与使用 ECB 的老旧系统互通,应该把这当作迁移它的理由,而不是复制这个弱点的理由。
由于大多数人输入的是口令而不是 32 字节的随机密钥,本工具会用 PBKDF2-HMAC-SHA256、600,000 次迭代和一个 16 字节随机盐从你的口令派生出 AES 密钥,这与当前的 OWASP 密码存储指南(以及要求盐至少 128 位的 NIST SP 800-132)保持一致。这会让暴力破解一个弱口令变得缓慢,但这并不是魔法:这是一个用来学习模式、调试密文和处理一次性个人数据的工具 —— 而不是用来保护生产环境机密的工具,那些应该交给专门的密钥管理系统。要生成一个强口令,可以使用我们的随机密码生成器;要获得真正随机的密钥,请使用密钥生成器。
// AES-256-GCM with a passphrase (PBKDF2-HMAC-SHA256, 600,000 iterations).
// Identical code runs in the browser and in Node.js 20+ via Web Crypto.
async function aesGcmEncrypt(plaintext, passphrase) {
const enc = new TextEncoder();
const salt = crypto.getRandomValues(new Uint8Array(16));
const iv = crypto.getRandomValues(new Uint8Array(12));
const baseKey = await crypto.subtle.importKey(
'raw', enc.encode(passphrase), 'PBKDF2', false, ['deriveKey']);
const key = await crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt, iterations: 600000, hash: 'SHA-256' },
baseKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
const ct = new Uint8Array(await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv }, key, enc.encode(plaintext)));
const packed = new Uint8Array([...salt, ...iv, ...ct]); // salt(16) | iv(12) | ct+tag
return btoa(String.fromCharCode(...packed)); // self-contained Base64
} 核心特性
默认使用 GCM 认证加密
GCM 会生成密文以及一个 128 位认证标签,因此只要有一个字节被改动,解密就会明确失败。需要与其他系统互通时,CBC 和 CTR 也只需一次点击即可切换。
自包含密文
口令模式会把随机盐、IV 和标签打包进同一个 Base64 字符串,因此解密方只需要口令即可 —— 不需要单独复制或担心遗漏其他字段。
口令或原始密钥
输入一个口令(会用 PBKDF2-HMAC-SHA256 迭代 600,000 次进行拉伸),或粘贴一个精确的 128/192/256 位密钥(十六进制或 Base64),实时的字节数徽章会确认长度是否正确。
与 OpenSSL 兼容的输出
开启 OpenSSL 模式即可生成 openssl enc 命令和 CryptoJS 都能读取的 Salted__ 格式,并实时显示等效的 CLI 命令,方便你在终端中复现。
100% 在你的浏览器中运行
每个字节都通过 Web Crypto API 在本地加密。打开「网络」面板,你会看到没有任何数据离开页面 —— 它甚至可以离线工作。
Base64 或 Hex 输出
以目标系统所需的编码复制结果,并在分段明细条中查看盐、IV、密文和标签的长度。
AES 加密示例
GCM + 口令(自包含、非确定性)
The quick brown fox jumps over the lazy dog.
盐 (16 字节) + IV (12 字节) + 密文 + 标签 (16 字节),经 Base64 编码 —— 每次运行都会得到不同的值
当模式为 GCM、密钥长度为 256、密钥类型为「口令」、口令为 hunter2 时,这句话会被加密成一个自包含的 Base64 字符串。加密两次会得到两个完全不同的结果 —— 这是有意为之。口令模式在每次加密时都会生成全新的 16 字节盐和全新的 12 字节 IV,因此相同的明文永远不会产生相同的密文,观察者也无法判断两条消息是否相同。输出下方的分段条会显示确切的结构:先是盐,然后是 IV,最后是附带 128 位 GCM 标签的密文。要解密,接收方只需要口令以及相同的模式和密钥长度 —— 盐、IV 和标签都包含在字符串内部。
与 OpenSSL 兼容的输出(CBC + 口令)
Attack at dawn!
U2FsdGVkX18AESIzRFVmd1PBwxIFQpF+VgIhTK0aDHQ=
开启「OpenSSL 兼容」模式,模式选 CBC,密钥类型选「口令」,口令为 correct-horse,KDF 选 PBKDF2,迭代次数 10,000。工具随即会生成 OpenSSL 的 Salted__ 格式:以 U2FsdGVkX1 开头的 Base64 字符串,这正是 8 字节 Salted__ 头部的 Base64 编码。由于每次都会生成一个全新的随机 8 字节盐,具体字符串每次都不同,但每一个都能在命令行用下面的命令解密:echo 'U2FsdGVkX18AESIzRFVmd1PBwxIFQpF+VgIhTK0aDHQ=' | openssl enc -d -aes-256-cbc -pbkdf2 -iter 10000 -pass pass:correct-horse -base64 -A —— 输出结果是 Attack at dawn!。若要匹配 CryptoJS 或 OpenSSL 1.0.2 及更早版本,请选择 EVP-MD5 而不是 PBKDF2。注意 openssl enc 不支持 GCM,因此 OpenSSL 模式仅支持 CBC。
如何用 AES 加密文本
- 1
选择模式和密钥长度
将模式保留为 GCM(推荐),密钥长度保留为 256,这是最合理的强安全默认值。只有当你要对接的系统要求时才切换到 CBC 或 CTR。
- 2
选择口令或原始密钥
将密钥类型保留为「口令」并输入一个强口令,或者切换到「原始密钥」并粘贴一个精确的 128/192/256 位密钥(十六进制或 Base64)。字节数徽章会确认你的原始密钥长度是否有效。
- 3
输入要加密的文本
输入或粘贴你的明文。加密会随着你的输入自动进行,完全在浏览器中运行 —— 无需点击按钮,也不会上传任何数据。
- 4
复制自包含的密文
右侧的 Base64 结果已经包含了盐、IV 和认证标签。使用分段条查看字节结构,然后点击「复制」。如果目标系统需要十六进制格式,可将输出编码切换为 Hex。
- 5
需要时再解密回来
把密文、口令以及相同的模式和密钥长度提供给接收方,或者打开 AES 解密页面自己反向解密。
常见的 AES 加密错误
把口令和原始密钥搞混
原始密钥必须恰好是 16、24 或 32 字节的随机数据(以十六进制或 Base64 输入);口令则可以是任意文本,必须先经过 KDF 拉伸。选择「原始密钥」却粘贴一段人类可读的口令,要么因长度不对而报错,要么会产生一个薄弱的密钥。
Key type: Raw key Key (hex): correct horse battery staple (not hex, not 32 bytes)
Key type: Passphrase Passphrase: correct horse battery staple (stretched with PBKDF2)
对同一密钥重复使用 IV
在给定密钥下,IV 必须对每条消息都是唯一的。重复使用它对 GCM 是致命的(可能泄露认证密钥),也会破坏 CBC 和 CTR 的机密性。让工具每次都生成一个全新的随机 IV。
// same key, same IV for two messages encrypt(key, iv, a); encrypt(key, iv, b);
// fresh random IV each time (the default) encrypt(key, randomIV(), a);
丢失了盐、IV 或标签
如果你只复制了密文字节,丢掉了前面拼接的盐/IV —— 或后面附加的 GCM 标签 —— 数据就永远无法解密。请保留完整的自包含字符串,而不只是其中的一部分。
stored = ciphertext // salt + IV + tag thrown away
stored = salt + iv + ciphertext + tag // the full Base64 string
以为 GCM 每次输出都应该一样
GCM(以及一般的口令模式)使用随机的盐和 IV,因此相同的文本每次加密都会得到不同的 Base64 字符串。这是一项安全特性,而不是缺陷 —— 它意味着窃听者无法判断两段密文是否加密的是同一条消息。
assert(encrypt(msg) === encrypt(msg)) // fails — and should
assert(decrypt(encrypt(msg)) === msg) // this is what must hold
AES 加密能做什么
- 了解 AES 各模式的行为
- 用相同的输入在 GCM、CBC 和 CTR 之间切换,观察认证方式、IV 长度和密文大小如何变化 —— 这是理解 NIST SP 800-38D 具体规定内容的实践方式。
- 生成其他系统可读取的密文
- 以 OpenSSL 的 Salted__ 格式(或原始密钥加 IV 的形式)生成输出,让使用 openssl 或加密库的后端、脚本或队友可以毫无阻碍地解密它。
- 加密一段简短的笔记或片段
- 用只有你自己知道的口令保护一次性的个人文本 —— 比如在设备间迁移的恢复助记词,或工单里的一段片段。不适合受监管或生产环境的机密。
- 为加密格式做原型验证
- 在编写代码之前,先在这里确定好盐/IV/标签的排布和 KDF 设置,用分段明细来确认字节顺序和长度。
- 生成测试向量
- 用固定的口令和模式生成已知密文,用于你自己的解密测试,然后在 AES 解密页面验证往返是否正确。
AES 模式与密钥派生
- GCM(Galois/Counter 模式)—— 带认证,推荐使用
- 在机密性之外还带有 128 位认证标签(NIST SP 800-38D)。它使用 96 位(12 字节)的 IV,每次加密都随机生成,加密和解密都能很好地并行化。有一条规则绝不能打破:绝不能对同一密钥重复使用 IV。SP 800-38D 将单个密钥限制为约 2^32 个随机生成的 IV,一旦重复,就会泄露两段明文的异或结果,甚至可能暴露保护标签的认证密钥。适合几乎所有场景。
- CBC(密码分组链接)—— 仅提供机密性
- 每个分组都会与前一个密文分组进行异或运算,使用一个随机的 16 字节 IV。它没有内置认证,因此必须搭配单独的 MAC —— 先加密后 MAC,例如使用我们的 HMAC 生成器 —— 而且历史上容易受到填充预言机攻击(Vaudenay,EUROCRYPT 2002)。提供此模式是为了与 OpenSSL 和老旧系统互通。
- CTR(计数器模式)—— 仅提供机密性,类似流密码
- 通过加密一个计数器,把 AES 变成流密码,因此任意字节长度都无需填充即可处理,各分组也能自由并行。和 CBC 一样,它本身不提供完整性保护,在同一密钥下重复使用计数器/IV 是灾难性的。适合需要随机访问或流式语义的场景。
- ECB —— 未提供(刻意如此)
- 电子密码本模式独立加密每个分组,因此相同的明文分组会产生相同的密文,模式会因此泄露 —— 这就是臭名昭著的「ECB 企鹅」。Web Crypto API 刻意没有实现它,我们也是如此。如果某个老旧的对端要求使用 ECB,应该把它当作需要修复的问题,而不是需要复现的格式。
- 密钥派生:600,000 次 vs 10,000 次 vs 1 次迭代
- 在默认的口令模式下,本工具按照 OWASP 的建议使用 PBKDF2-HMAC-SHA256、迭代 600,000 次(相当于把同一个 SHA-256 哈希应用数十万次)并配合一个 16 字节的盐。在 OpenSSL 兼容模式下,PBKDF2 默认只迭代 10,000 次(openssl enc 的默认值),而 CryptoJS 和旧版 OpenSSL 使用的传统 EVP_BytesToKey KDF 只运行一次 MD5 —— 强度低了几个数量级。迭代次数越多,每次猜测的暴力破解速度就越慢,这也是现代默认值大幅提高的原因。Argon2 和 scrypt 更强,但不属于 Web Crypto 的一部分,因此不在本工具的范围内;对于密码存储,请遵循 OWASP 的建议,优先选择 Argon2id。
AES 加密最佳实践
- 优先选择 GCM,除非对端另有要求
- 认证加密能捕获 CBC 和 CTR 会悄悄放过的篡改。只有在需要互通时才降级到 CBC 或 CTR,如果这样做,请务必加上 MAC。
- 为每条消息使用全新的随机 IV
- 本工具会自动完成这一点。如果你手动覆盖 IV,切勿对同一密钥重复使用同一个 IV —— 对 GCM 而言重复是灾难性的,对 CBC 而言会破坏语义安全性。
- 把盐、IV 和标签与密文放在一起
- 它们不是秘密,但没有它们解密就会失败。本工具的自包含格式已经把三者都打包在一起;如果你使用原始密钥的裸密文模式,请单独复制 IV,并把它和密文一起保存。
- 不要在任何在线工具中加密生产环境或受监管的机密
- 即便完全在客户端运行,浏览器工具也只适合学习、调试和个人一次性用途。真正的机密应该交给经过审核、拥有审计级密钥处理和轮换机制的密钥管理系统。AES-256 本身是强健的 —— 已被 NSA CNSA 2.0 套件批准用于「绝密」级别信息 —— 现实中的破解都源自实现上的失误,而不是密码算法本身。
AES 加密常见问题
在线加密文本安全吗?
AES 能在没有密钥的情况下被解密吗?
GCM 与 CBC —— 应该用哪种模式?
AES-128 与 AES-256 —— 256 位值得选吗?
在这里加密时,我的数据会被上传吗?
口令和密钥有什么区别?
我能加密成 OpenSSL 或 CryptoJS 可以解密的格式吗?
相关工具
查看所有工具 →AES 解密工具 — 兼容 OpenSSL 与 CryptoJS
安全工具
在线解密 AES —— 支持 GCM/CBC/CTR、口令或原始密钥,自动识别 OpenSSL 与 CryptoJS 的 "U2FsdGVkX1" 格式。100% 浏览器本地运行,密钥永不离开页面。
Bcrypt 哈希生成器与验证器
安全工具
在线生成并验证 bcrypt 密码哈希——可调成本因子,支持 $2b$/$2a$/$2y$ 前缀。100% 在浏览器中运行,密码绝不上传。
HMAC 生成器与签名校验工具
安全工具
免费在线 HMAC 生成与校验工具。支持文本、Hex 或 Base64 密钥计算 HMAC-SHA256/SHA1/SHA384/SHA512,输出 Hex/Base64/Base64URL。100% 在浏览器中运行 —— 密钥永不离开页面。
JWT 解码器 · 在线解码工具
安全工具
免费 JWT 解码器,在线即时解码 JWT 令牌。查看头部、载荷、签名以及过期时间、算法和声明详情。100% 浏览器本地运行——令牌绝不离开你的设备。无需注册、无跟踪。
JWT 编码器与生成器
安全工具
免费在线 JWT 生成器与编码器。构建头部和载荷,使用 HS256、RS256 或 ES256 即时签名。100% 浏览器本地运行——你的密钥和私钥绝不离开设备。
免费 JWT 密钥生成器 — HS256/384/512
安全工具
为 HS256/384/512 生成强壮、符合 RFC 规范的 JWT 密钥——100% 在浏览器中运行,绝不发往服务器。支持 base64url、base64 或 hex,可复制到 .env。