AES 加密解密:在线工具
传输敏感数据、加密配置文件、保护用户隐私——AES 是对称加密的事实标准。本文详解 AES 加密原理和工具用法。
什么是 AES?
AES(Advanced Encryption Standard)是美国 NIST 制定的对称加密标准,2001 年发布。特点:
- 对称加密:加密和解密用同一密钥
- 块加密:每次加密 16 字节(128 位)数据块
- 安全性高:截至 2026 年无已知实际攻击
- 速度快:硬件加速广泛支持
AES 三个版本
| 版本 | 密钥长度 | 轮数 | 安全性 |
| AES-128 | 128 位(16 字节) | 10 | 高 |
| AES-192 | 192 位(24 字节) | 12 | 更高 |
| AES-256 | 256 位(32 字节) | 14 | 最高 |
实际应用多选 AES-128 或 AES-256。
加密模式
ECB(Electronic Codebook)
最简单,每块独立加密:
明文块 1 → 加密 → 密文块 1
明文块 2 → 加密 → 密文块 2
特点:
- 简单快速
- 相同明文块加密后相同密文块
- 不安全,泄露模式
CBC(Cipher Block Chaining)
每块与前一块密文异或:
明文块 1 XOR IV → 加密 → 密文块 1
明文块 2 XOR 密文块 1 → 加密 → 密文块 2
特点:
- 需要 IV(初始化向量)
- 相同明文加密结果不同
- 主流模式
GCM(Galois/Counter Mode)
加密 + 认证:
加密 + 生成认证标签(MAC)
特点:
- 同时保证机密性和完整性
- 推荐使用
- 性能好,硬件加速
其他模式
- CFB、OFB、CTR:流式加密模式
52tool AES 加密工具
工具地址:哈希计算(含 AES)
功能
- AES-128/192/256
- ECB/CBC/CTR/GCM 模式
- PKCS7 / NoPadding 填充
- 密钥、IV 输入
- 输出 Base64 或 Hex
- 浏览器端处理
实战 1:AES-128-CBC 加密
输入:
模式:AES-128-CBC
密钥:1234567890123456(16 字节)
IV:1234567890123456(16 字节)
明文:Hello, World!
输出:Base64
输出:
密文:U2FsdGVkX1+...
实战 2:AES-256-GCM 加密
输入:
模式:AES-256-GCM
密钥:32 字节随机
IV:12 字节随机
明文:Confidential data
输出:
密文 + 认证标签
实战 3:解密
输入:
模式:AES-128-CBC
密钥:1234567890123456
IV:1234567890123456
密文:U2FsdGVkX1+...
输出:
明文:Hello, World!
加密流程详解
1. 准备密钥
密钥长度必须严格匹配:
AES-128:16 字节
AES-192:24 字节
AES-256:32 字节
密钥生成:
import secrets
key = secrets.token_bytes(32) # AES-256
2. 准备 IV
CBC、CTR、GCM 需要 IV:
- CBC/CTR:16 字节
- GCM:12 字节(推荐)
IV 必须随机,每次加密用不同的。IV 不需要保密。
3. 填充明文
明文不是 16 字节倍数时填充(CBC、ECB):
- PKCS7:填充字节 = 缺的字节数
- PKCS5:同 PKCS7 但只支持 8 字节块
- NoPadding:明文必须是 16 字节倍数
GCM、CTR 不需要填充。
4. 加密
密文 = AES_encrypt(明文, 密钥, 模式, IV)
5. 传输密文 + IV
接收方需要密文和 IV 才能解密。IV 可与密文一起传输(不需保密)。
编程实现
JavaScript(Web Crypto API)
// AES-256-GCM 加密
async function encrypt(text, password) {
const enc = new TextEncoder();
const salt = crypto.getRandomValues(new Uint8Array(16));
// 从密码派生密钥
const keyMaterial = await crypto.subtle.importKey(
'raw', enc.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 iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv },
key,
enc.encode(text)
);
return { salt, iv, ciphertext };
}
// 解密
async function decrypt({ salt, iv, ciphertext }, password) {
const enc = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey(
'raw', enc.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,
['decrypt']
);
const decrypted = await crypto.subtle.decrypt(
{ name: 'AES-GCM', iv },
key,
ciphertext
);
return new TextDecoder().decode(decrypted);
}
Python(cryptography)
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os
# 加密
key = os.urandom(32) # AES-256
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
encryptor = cipher.encryptor()
# PKCS7 填充
from cryptography.hazmat.primitives import padding
padder = padding.PKCS7(128).padder()
padded = padder.update(b'Hello, World!') + padder.finalize()
ciphertext = encryptor.update(padded) + encryptor.finalize()
# 解密
decryptor = cipher.decryptor()
padded = decryptor.update(ciphertext) + decryptor.finalize()
unpadder = padding.PKCS7(128).unpadder()
plaintext = unpadder.update(padded) + unpadder.finalize()
Java
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.SecureRandom;
// 加密
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(256);
SecretKey key = kgen.generateKey();
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal("Hello".getBytes());
Go
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
)
key := make([]byte, 32)
rand.Read(key)
block, _ := aes.NewCipher(key)
iv := make([]byte, aes.BlockSize)
rand.Read(iv)
stream := cipher.NewCTR(block, iv)
ciphertext := make([]byte, len(plaintext))
stream.XORKeyStream(ciphertext, plaintext)
命令行(OpenSSL)
# 加密
echo "Hello, World!" | openssl enc -aes-256-cbc -pbkdf2 -pass pass:password -base64
# 解密
echo "U2FsdGVkX1+..." | openssl enc -aes-256-cbc -d -pbkdf2 -pass pass:password -base64
实战场景
场景 1:加密配置文件
数据库密码、API 密钥存配置文件:
加密前:
DB_PASSWORD=myPassword123
加密后:
DB_ENCRYPTED=U2FsdGVkX1+...
应用启动时用主密钥解密。
场景 2:用户数据加密
# 加密用户敏感数据
def encrypt_user_data(data, key):
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.GCM(iv))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(data) + encryptor.finalize()
return iv + encryptor.tag + ciphertext
场景 3:文件加密
# 加密文件
openssl enc -aes-256-cbc -pbkdf2 -in secret.pdf -out secret.enc -pass pass:password
# 解密
openssl enc -aes-256-cbc -d -pbkdf2 -in secret.enc -out secret.pdf -pass pass:password
场景 4:API 数据加密
前后端通信加密:
前端用 AES 加密请求数据 → 服务器用 AES 解密
服务器用 AES 加密响应数据 → 前端用 AES 解密
场景 5:HTTPS 之外额外加密
HTTPS 已加密传输,但仍可能被中间人解密(如企业代理)。敏感数据额外 AES 加密。
密钥管理
1. 密钥生成
import secrets
key = secrets.token_bytes(32) # 安全随机
不要用时间戳、Math.random() 等不安全随机源。
2. 密钥存储
- 环境变量
- 密钥管理服务(AWS KMS、HashiCorp Vault)
- 硬件安全模块(HSM)
不要把密钥硬编码在代码中。
3. 密钥派生
从用户密码派生 AES 密钥:
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000
)
key = kdf.derive(password.encode())
4. 密钥轮换
定期更换密钥:
- 主密钥:每 3-6 个月
- 数据加密密钥:每次加密用新 IV 即可
安全注意事项
1. 不要用 ECB
ECB 不安全,相同明文块加密后相同密文块。用 CBC 或 GCM。
2. IV 必须随机
IV 不能重复,否则攻击者能获取信息。
3. 用 GCM 而非 CBC
GCM 提供认证,防止密文被篡改。CBC 不防篡改。
4. 密钥长度足够
至少 128 位(16 字节),重要数据用 256 位。
5. 密钥不能硬编码
# 错误
KEY = b'mysecretkey1234567890123456789'
# 正确
import os
KEY = os.environ.get('AES_KEY').encode()
6. 不要用密码直接作密钥
用户密码长度不一,需用 KDF(如 PBKDF2)派生固定长度密钥。
与其他加密方式对比
AES vs RSA
| 维度 | AES | RSA |
| 类型 | 对称 | 非对称 |
| 速度 | 快 | 慢 |
| 密钥 | 一个 | 公私钥对 |
| 用途 | 大数据加密 | 小数据、密钥交换 |
常用组合:RSA 加密 AES 密钥,AES 加密数据。
AES vs ChaCha20
| 维度 | AES | ChaCha20 |
| 硬件加速 | 有 | 无需 |
| 软件实现 | 慢 | 快 |
| 移动端 | 略慢 | 快 |
移动端 ChaCha20 更优,TLS 1.3 两者都支持。
AES vs DES
DES 已被破解,不要用。AES 是替代品。
与其他工具配合
AES + 哈希
工具:MD5/SHA256
用哈希验证密钥或数据完整性。
AES + Base64
工具:Base64 编解码
AES 密文常以 Base64 表示便于传输。
AES + JWT
工具:JWT 解码器
JWT 用 HMAC(不是 AES),但有些 JWT 实现用 AES 加密 payload(JWE)。
常见问题
Q: AES 是加密的吗?
A: 是的。AES 是真正的加密算法,不是编码(Base64 是编码,不是加密)。
Q: AES 能破解吗?
A: 截至 2026 年无已知实际攻击。暴力破解 AES-256 需要 2^256 次运算,宇宙寿命内不可行。
Q: AES 密钥怎么生成?
A: 用密码学安全随机数生成器。Python: secrets.token_bytes(32)。JavaScript: crypto.getRandomValues()。
Q: IV 是什么?必须保密吗?
A: 初始化向量,每次加密用不同的。IV 不需要保密,但必须随机。
Q: AES 加密能解密吗?
A: 能。AES 是对称加密,用相同密钥能解密。如果密钥丢失,数据无法恢复。
Q: 工具会泄露我的密钥吗?
A: 52tool AES 工具在浏览器端运行,密钥不上传服务器。但仍建议敏感数据用本地工具(OpenSSL 命令行)处理。
常见问题解答
Q: 怎么用 AES 加密文本?
A: 1) 打开 52tool AES 加密;2) 选 AES-128/256;3) 选 CBC/GCM;4) 输入密钥和 IV;5) 输入明文;6) 加密得到密文。
Q: AES-128 和 AES-256 哪个好?
A: AES-256 更安全,但 AES-128 已足够。性能上 AES-128 略快。重要数据用 AES-256。
Q: ECB 和 CBC 哪个好?
A: CBC。ECB 不安全,相同明文块加密后相同密文块,泄露模式。
Q: 密钥忘了能找回吗?
A: 不能。AES 是真加密,无密钥无法解密。务必安全保存密钥。
Q: 怎么从用户密码生成密钥?
A: 用 PBKDF2/Argon2 等 KDF(密钥派生函数):
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000)
key = kdf.derive(password.encode())
Q: GCM 模式为什么推荐?
A: GCM 同时提供加密和认证。防篡改、防重放,比 CBC 更安全。现代应用首选 GCM。
总结
AES 是主流对称加密:
- 在线工具 → 52tool AES 加密
- 推荐 AES-256-GCM
- 密钥安全随机生成
- IV 每次不同,不需保密
记住:不用 ECB,密钥不硬编码,用 GCM 模式,密钥安全保存。