AES 在线加密解密

在浏览器里用 AES-256-GCM 加密解密文本和文件,支持密码或原始密钥(含 IV 与附加数据,可解微信支付回调),密码错误明确提示认证失败,不上传。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
「密码」:密码按输入的原样以 UTF-8 编码,加上每次新生成的 16 字节盐,经 PBKDF2-HMAC-SHA256 迭代 600,000 次得到 256 位密钥,密文以 v2: 开头。「原始密钥」:16、24 或 32 字节,可填十六进制、Base64 或文本(取其 UTF-8 字节),原样用作 AES 密钥,密文没有前缀。「随机生成」填入一个随机的 256 位密钥,写成十六进制;密钥格式选了 Base64 时写成 Base64。「显示」可查看输入的密码。
文本按 UTF-8 加密。点「文件…」或把文件拖到框里,可以改为加密文件:上限 256 MB,读入内存处理,结果是一个下载按钮,文件名为原名加 .enc。输入时不会自动加密:点「加密」,或按 Ctrl+Enter(Mac 为 ⌘+Enter)。解密出的文本也显示在这个框里。焦点在工具内时按 Ctrl+L(⌘+L),清空两个文本框、密码、密钥、IV、AAD 和已选的文件。
粘贴密文,带不带 v2: 前缀都可以,写法可以是 Base64(标准或 URL 安全字母表,填充可省略)或十六进制,其中的空格和换行会被忽略。没有前缀时,密码模式先按 PBKDF2 200,000 次尝试,再按 600,000 次。点「解密」,或在这个框里按 Ctrl+Enter(⌘+Enter),文本显示在明文框;不是 UTF-8 的字节改为提供下载。点「文件…」或拖入文件,可解密不超过 256 MB 的加密文件。「输出」决定新加密的文本写成 Base64 还是十六进制。「复制」复制这个框的内容。

AES-256-GCM(NIST SP 800-38D)· 密码模式:PBKDF2-HMAC-SHA256,600,000 次迭代,每次新的 16 字节盐 · 每次新的 12 字节 IV · 16 字节认证标签 · 在本标签页内运行,不上传任何内容

阅读完整使用指南 AES 在线加密解密工具:浏览器端 AES-GCM 加密完全指南
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

示例一:用密码加密一句话

明文 数据库只读账号下周一启用,密码 correct horse battery staple,某一次的输出:

v2:qXfeC+pkpC/F/K3PR6ucLX6MQOcmQtyj+UUn9SYWmygCNoyV6H080bCB6fI6r1FJzypkhN0oWVRkA1VMXiCkXm6soo3Tqi/PZM0fJ28ANQk=

这 12 个汉字按 UTF-8 是 36 字节,所以 v2: 后面的 108 个 Base64 字符解码后是 80 字节:16 字节盐 + 12 字节 IV + 36 字节密文 + 16 字节认证标签。用同一个密码解密即可还原;再点一次加密,输出会变,因为盐和 IV 都是新的。

示例二:解密微信支付 APIv3 回调报文

微信支付的回调通知与平台证书下载接口用 AEAD_AES_256_GCM 加密 resource 字段,密钥是 32 字节的 APIv3 密钥,nonce 与 associated_data 按字符串参与解密,ciphertext 是 Base64 编码、末尾带 16 字节认证标签(见微信支付「如何解密回调报文和平台证书」,2024-11-29 更新)。在本工具里这样填:

回调字段本工具示例值(虚构)
APIv3 密钥原始密钥,格式选「文本(UTF-8)」zerotool-example-apiv3-key-0032b
nonceIV 输入框0123456789ab
associated_dataAAD 输入框transaction
ciphertext密文框TB0zfn/fWCjPw0A+a0ZbgqZ7CKokDC839Nw4ZaBq0aOtwBqOthxnj5Ak4KGHMF7BQ5W3PA72tzCaHxynWKK+5mdrbhBQFtsS

点解密得到 {"out_trade_no":"ZT20260930001","trade_state":"SUCCESS"}。IV 规则:正好 24 位十六进制时按 12 字节读取,其他内容按文本的 UTF-8 字节读取,所以 12 位的 0123456789ab 按文本处理,与微信支付一致。把 AAD 改成 certificate 或清空,工具会提示认证失败。上面的密钥与报文是按同样规则用 Node.js 生成的示例;排查真实回调时,APIv3 密钥只在本机内存中使用,不会发往任何服务器。

报错说明

输入提示
示例一的密文,密码输错认证失败:密码或密钥不对,或者密文被改动、被截断。没有解密出任何内容。
U2FsdGVkX1… 开头的密文这是 OpenSSL enc 或 CryptoJS 的输出……
把 v2: 改成 v3:未知的密文版本「v3:」。
密文中间混进一个全角字符第 N 个字符「…」不是 Base64 字符。
密钥类型为原始密钥时粘贴 v2: 密文这段密文以「v2:」开头,是用密码加密的。

如果密钥正确,但解出的字节不是 UTF-8 文本,工具会提供下载,不会显示乱码。

密文格式与 Python 代码

  • 密码模式:v2: + Base64(或十六进制)的「盐 16 字节 | IV 12 字节 | 密文 | 认证标签 16 字节」,密钥由 PBKDF2-HMAC-SHA256 迭代 600,000 次得到 32 字节,取自 OWASP 密码存储速查表。
  • 无前缀:同样的布局,是本页 2026-09-30 之前生成的(20 万次迭代)。工具先试 20 万次,再试 60 万次,因此也能读取其他程序按同一布局写出的密文。
  • 原始密钥模式:Base64 或十六进制的「IV 12 字节 | 密文 | 认证标签」;填了 IV 时只有「密文 | 认证标签」,与微信支付的 ciphertext 相同。
  • 文件:同样的字节,不做 Base64;密码模式的文件以 v2: 三个字节开头。

下面的 Python 代码(cryptography 45)与本工具互通:

import base64, os
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

def _key(password: str, salt: bytes, iterations: int) -> bytes:
    kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=iterations)
    return kdf.derive(password.encode("utf-8"))

def encrypt(text: str, password: str) -> str:
    salt, iv = os.urandom(16), os.urandom(12)
    ct = AESGCM(_key(password, salt, 600_000)).encrypt(iv, text.encode("utf-8"), None)
    return "v2:" + base64.b64encode(salt + iv + ct).decode()

def decrypt(token: str, password: str) -> str:
    # 有 "v2:" 前缀为 60 万次迭代;无前缀为本工具 2026-09-30 之前的格式(20 万次)
    token = token.strip()
    iterations = 600_000 if token.startswith("v2:") else 200_000
    data = base64.b64decode(token.removeprefix("v2:"))
    salt, iv, ct = data[:16], data[16:28], data[28:]
    return AESGCM(_key(password, salt, iterations)).decrypt(iv, ct, None).decode("utf-8")

def decrypt_raw(token: str, key_hex: str) -> str:
    # 原始密钥模式、IV 输入框留空:Base64 或十六进制的 iv(12) | 密文 | 标签(16)
    token = token.strip()
    is_hex = all(c in "0123456789abcdefABCDEF" for c in token)
    data = bytes.fromhex(token) if is_hex else base64.b64decode(token)
    return AESGCM(bytes.fromhex(key_hex)).decrypt(data[:12], data[12:], None).decode("utf-8")

OpenSSL 与 CBC 密文

openssl enc 读不了这种格式:openssl-enc 手册写明该命令不支持 CCM、GCM 等认证加密模式,以后也不会支持;OpenSSL 3.6.1 对 -aes-256-gcm 的回应是 enc: AEAD ciphers not supported。

以 U2FsdGVkX1 开头的密文是「Salted__」的 Base64,来自 openssl enc 或 CryptoJS 的 AES.encrypt(文本, “口令”),一般是 AES-256-CBC。CBC 没有认证标签,密码错了也可能输出乱码。本工具识别到这个头会直接说明,请改用下面的命令(2026-09-30 实测):

# 用 openssl enc -pbkdf2 加密的
openssl enc -d -aes-256-cbc -pbkdf2 -a -A -in message.txt
# 用 CryptoJS 4.2.0 AES.encrypt(文本, "口令") 加密的
openssl enc -d -aes-256-cbc -md md5 -a -A -in message.txt

与其他 AES 在线工具的实测差异

2026-09-30 用桌面版 Chromium、同一段测试文本,观察页面发出的请求:

  • 锤子在线工具(toolhelper.cn):点加密后把密钥、IV 与明文一起 POST 到 /SymmetricEncryption/AesEncrypt,在服务器端加密。它也有 GCM 的 nonce 与附加数据输入框,但用它解微信支付回调就意味着把 APIv3 密钥交给第三方服务器。
  • 在线工具大全(lddgo.net):把明文与密码 POST 到 openapi.lddgo.net,默认模式是 ECB。
  • CoderTools(codertools.net):在浏览器内运行,默认 CBC、密钥按文本;密钥错误时结果框为空,没有任何提示。

本工具只做 GCM,但每种失败都有明确提示,支持单独的 IV 与附加数据、文件加解密,页面不加载统计与广告。

限制

  • 只支持 GCM,不做 CBC、ECB、CTR,读不了 openssl enc 与 CryptoJS 的输出,请用上面的命令。
  • 密码模式格式固定(PBKDF2-HMAC-SHA256、60 万次、16 字节盐、无附加数据),认证标签固定 128 位。
  • 文件上限 256 MB,整个在内存中处理。测试笔记本上 200 MB 文件约 0.8 秒,5 MB 文本约 1.7 秒(主要花在绘制文本框)。
  • 原始密钥配随机 96 位 IV 时,NIST SP 800-38D 第 8.3 节规定同一密钥最多加密 232 次;密码模式每次都派生新密钥。
  • 文件名不加密,合同.pdf.enc 仍能看出原名;加密文件本身不保存文件名。
  • 弱密码加密后依然是弱密码,可用密码生成器生成;解密出的文件可用文件哈希校验核对 SHA-256。

FAQ

这个工具用的是 AES 的哪种模式?

只用 AES-GCM。密码模式是 AES-256-GCM,密钥由 PBKDF2-HMAC-SHA256 派生;原始密钥模式按密钥长度使用 AES-128、AES-192 或 AES-256。GCM 带 16 字节认证标签,密码不对或密文被改动时会提示「认证失败」,不会输出乱码。

同样的明文和密码,为什么每次加密结果都不一样?

每次加密都会重新生成 16 字节的随机盐和 12 字节的随机 IV。NIST SP 800-38D 要求同一密钥下 IV 不能重复,新盐也会派生出新密钥。这些不同的密文都能解密回同一段明文。

能用 OpenSSL 解密这里生成的密文吗?

不能。openssl enc 不支持 GCM,其手册写明以后也不会支持。请用本页的 Python 代码、Web Crypto API 或任意 AES-GCM 库按下文的字节布局解密。反过来,把 openssl enc 或 CryptoJS 生成的密文(以 U2FsdGVkX1 开头)粘进来,工具会识别出来并告诉你用哪条 openssl 命令。

我的文本、密码或文件会被上传吗?

不会。加解密都在浏览器标签页内通过 Web Crypto API 完成。页面不保存输入、不把输入写进网址,也不加载 Google Analytics 与 AdSense。

解微信支付回调时总是认证失败,常见原因是什么?

按微信支付文档,密钥是 32 字节的 APIv3 密钥字符串(密钥格式选「文本(UTF-8)」,不是十六进制或 Base64),nonce 与 associated_data 都按字符串原样填入 IV 与 AAD 输入框。associated_data 填错或漏填(文档注明它可能为空,为空时 AAD 框也留空)、密钥格式选成十六进制,都会导致认证失败。