目录

为什么 AES 在线加密每次结果不一样(CryptoJS 库)

某次在使用 AES 在线加密网站的时候遇到了两个问题:

  1. 相同明文和密钥的情况下,每次加密结果不一致,但都可以正常解密出相同的明文。
  2. 密钥长度无需指定,甚至用空密钥也可以。

示例网站:在线 AES 加密 | AES 解密 - 在线工具 (sojson.com)

问题分析

密文内容会变,base64 编码,开头一段总是固定的字符。虽然每次加密结果不一致,但开头的一段数据总是 U2FsdGVkX1,于是先解 base64 查看有没有可读的内容。

密文总是以 Salted__ 开头,看来是加了盐,密文中应该包含了盐的信息。

查看源码

查看网站代码,看样子是使用了一个叫做 CryptoJS 的第三方库。在 npm 上能找到 crypto-js,可阅读代码。

通过查看源码(cipher-core.js 第 646 行左右),parse 函数的作用是解析出实际密文和 salt 值。以 word 为单位将原密文分割为数组,判断开头是否是 Salted__,如果是则解析出盐值,去掉开头和盐值后剩下的就是实际密文。

结论

进一步阅读源码可知:

  • 盐值是随机生成,不需要指定盐值。
  • 同时有一个密钥派生函数,根据输入的字符串派生出符合长度要求的密钥,所以即使用户输入的密钥长度不满足条件,也是可以正常加密的。