tools / aes
aes/
AES 对称加密和解密。模式、填充、密钥和 IV 的格式、字符集都可以选,结果和 Java、CryptoJS 一致,密钥不会离开浏览器。
明文
密文
历史记录
每次加密、解密成功后自动记一条,保留最近 20 条,只存在这台设备的浏览器里。不保存密钥,但会保存 IV 和解密出的明文,在公用电脑上用完请清空记录。
AES、DES、RSA 是什么,有什么区别
AES 和 DES 是对称加密:加密和解密用同一把密钥,就像同一把钥匙锁门也开门。它们速度快,适合加密大量数据,难处在于怎么把这把密钥安全地交给对方。
DES 是上世纪 70 年代的老标准,有效密钥只有 56 位,现在用专门的硬件或计算机集群可以暴力穷举破解,只适合对接还在用它的老系统。AES 是取代 DES 的新标准,密钥 128、192 或 256 位,目前没有可行的破解方法,是现在加密数据的首选。
RSA 是非对称加密:有一对密钥,公钥可以公开给任何人,用来加密;私钥自己保管,用来解密。就像一个谁都能往里投信、只有你有钥匙的信箱。好处是不用事先约定密钥,缺点是很慢,一次只能加密几百字节。实际系统常把两者结合:先用 RSA 加密一把随机生成的 AES 密钥发给对方,再用 AES 加密真正的数据。
加密模式是什么,选哪个
AES 每次只能加密 16 字节,模式决定一长串数据怎么切块、块与块之间怎么关联。ECB 每块单独加密,相同的内容会得到相同的密文,会暴露数据规律,不推荐。CBC 让每块先和上一块的密文混合再加密,第一块和 IV 混合,是最常见的选择。CFB、OFB、CTR 把 AES 变成一串密钥流和数据逐字节异或,可以不填充。GCM 在 CTR 的基础上多算一个校验标签(Tag),密文被改动过就会解密失败,是现在最推荐的模式。
IV 和填充是干什么的
IV(初始向量)让同样的内容每次加密结果都不一样。它不需要保密,可以和密文一起传,但同一把密钥下不要重复使用,GCM 尤其如此。除 ECB 外都要 IV:GCM 推荐 12 字节,其他模式必须 16 字节。
ECB 和 CBC 要求数据长度是 16 字节的整数倍,不够时按填充方式补齐。PKCS5Padding 和 PKCS7Padding 对 AES 完全一样,是最常用的;ZeroPadding 补 0,解密时会去掉结尾所有的 0 字节,明文本身以 0 字节结尾时会一起被去掉;NoPadding 不补,要自己保证长度。GCM 不用填充。
和 Java、CryptoJS 的写法怎么对应
Java 的 Cipher.getInstance("AES/CBC/PKCS5Padding") 就是选 CBC 和 PKCS5Padding;只写 "AES" 时默认是 ECB 和 PKCS5Padding。Java 的 CTR 和 GCM 只能用 NoPadding,GCM 的 Tag 只支持 96 到 128 位。CryptoJS 的 CryptoJS.pad.Pkcs7 对应 PKCS7Padding,ZeroPadding、AnsiX923、Iso10126、Iso97971 同名对应。CryptoJS.AES.encrypt 直接传字符串口令时,会自动生成密钥并输出 U2FsdGVkX1 开头的结果,这种用法这里不支持,请传入 16、24 或 32 字节的密钥和 IV。
GCM 的 Tag 和 AAD 是什么
Tag 是 GCM 算出的校验值,加密结果的最后几个字节就是 Tag(128 位是 16 字节)。AAD 是附加认证数据,比如消息头,它本身不加密,但参与校验,解密时必须填一样的内容,否则会提示校验不通过。
常见问题
提示「密钥是 N 字节」或「IV 是 N 字节」怎么办
先看格式选对没有:同样 32 个字符,选 string 是 32 字节,选 hex 才是 16 字节。AES 密钥必须是 16、24 或 32 字节,除 ECB 和 GCM 外 IV 必须正好 16 字节,这里不会自动补零或截断,当前字节数显示在密钥和 IV 栏的标题旁。选 string 时字节数按所选字符集计算,一个汉字在 UTF-8 下占 3 字节。后端如果先对口令做了补零、取哈希之类的处理,请先算出最终的字节,再用 hex 或 base64 格式填进来。
解密提示「填充不对」怎么办
说明解出来的最后一块不符合所选的填充规则,通常是密钥、IV、模式或填充方式有一项和加密时不一致,也可能是密文复制不完整。请逐项对照加密端的参数,密钥格式或密文格式(hex 和 base64)选错也会这样。ZeroPadding 和 NoPadding 不检查填充,选它们不会报这个错,但参数不对时结果会是乱码。
解密结果开头一段是乱码,或提示「不是有效的 UTF-8 文本」
先查 IV。密文超过一个块时,CBC 和 CFB 模式下 IV 不对,只会让第一个 16 字节的块出错,后面的内容正常,也不会报填充错误,现象就是开头乱码、后面是对的。如果提示结果不是有效的文本,也可能是字符集和加密端不一致,比如对方用的是 GBK。把输出格式改成 hex,可以先确认解出来的字节本身对不对。
GCM 解密提示「Tag 校验不通过」怎么办
说明密钥、IV、AAD、Tag 长度里有一项和加密时不一致,或者密文被改动过。这里把输入的最后一段当作 Tag,长度按「Tag 长度」选项(默认 128 位,即 16 字节),所以密文和 Tag 要连在一起填;如果对方把 Tag 单独给你,先接在密文后面。AAD 的格式默认是 hex,填 string 内容时记得改格式;加密时没填 AAD,解密时也要留空。
加密结果和 Java、Python 等后端对不上,怎么排查
按这个顺序核对:模式和填充、密钥和 IV 的格式与字节数、字符集、输入输出格式。string 格式的明文不会去掉首尾空白,末尾多一个换行就是另一段数据。CTR、CFB、OFB 在这里也会按所选填充补齐,选 PKCS5Padding 时密文比明文长,后端用 NoPadding 的话这里也要选 NoPadding。CFB 是 128 位整块反馈,对方用 CFB8 的话对不上。
密文该选 hex 还是 base64,选错了会怎样
跟着对方的输出走:全是 0-9、a-f 的是 hex,带大小写字母、+、/ 或结尾 = 的是 base64。解密时选错不一定立刻报错,因为 hex 用到的字符都是合法的 base64 字符,只是解出来的字节不对,最后表现为「不是 16 的整数倍」或「填充不对」。base64 里的 - 和 _(URL 安全写法)和缺少的 = 都能识别,hex 里的空格、冒号和 0x 前缀会被忽略。
历史记录里存了什么,会上传吗
只存在这台设备浏览器的 localStorage 里,不会上传,页面代码里没有任何网络请求。每次成功加密或解密后记一条,最多保留 20 条,输入或结果超过 2 万字符的不记。记录里有参数、IV、AAD、输入和结果,以及一个由密钥算出的 8 位指纹(记录里 # 号后面的那串字符,用来区分是不是同一把密钥),不存密钥本身,所以点「填入」后要重新填密钥。每条可以单独删除,公用电脑上用完请点「清空记录」。
能自动生成随机密钥或 IV 吗
不能。这里没有生成按钮,密钥和 IV 要自己填。同样的明文、密钥、IV 和参数,每次加密的结果都一样,只有 ISO10126 填充会混入随机字节而使结果不同。需要随机值时可以自己生成,比如命令行里 openssl rand -hex 16 会输出 16 字节,格式选 hex 填进来即可。