始终为您的 AES 文件加盐。这样做的原因是说您有一个 JPEG 文件目录,这些文件使用相同的密码进行了密码加密,但没有盐。如果有人掌握了这些文件,他们将看到所有文件都以相同的字节开头(因为这是 JPEG 标头,并且相同的密码短语将始终加密为相同的值,直到字节开始不同,至少使用 CBC) ,他们还将知道文件的第一个块看起来像未加密。即使他们不知道自己是什么类型的文件,他们也可以从相似的前导长度和各种文件格式中猜出类型。
知道了这一点,他们可以以类似于彩虹表/蛮力的方式对您的密码进行逆向工程。加盐不会阻止这种情况的发生,但会使破解变得非常困难,因为每个文件(加盐之后)都会不同,因此文件类型识别很困难,而且他们必须为每个盐或计算开销生成彩虹表为盐创建一个初始化向量。
OpenSSL 将盐存储在文件中
例如我使用此命令创建了一个密码为“password”的文件:
echo "randomprhase" | openssl aes-128-cbc -out message.enc
这是生成文件的十六进制转储:-
[james@web openssltest]$ hexdump message.enc
0000000 6153 746c 6465 5f5f 7eaa c4fd 63d8 8c8c
0000010 9519 75c9 0497 d449 27f5 2c91 0d34 5ceb
0000020
当我再次运行加密时,同样的数据:-
[james@web openssltest]$ hexdump message1.enc
0000000 6153 746c 6465 5f5f a876 5394 53f1 bf1a
0000010 adcb e1cd dba9 8034 cf13 8b3f c37c 5048
0000020
前 4 个字节表示文件已加盐 (6153 746c 6465 5f5f),并且始终相同。
接下来的 4 个字节是随机盐(7eaa c4fd 63d8 8c8 for first file & a876 5394 53f1 bf1a for the second file)
OpenSSL 将使用这个盐并构建初始化向量 (IV),它是密码 + 盐重复 3 次的 MD5 散列。然后使用该 IV 加密文件。
请注意,每种情况下最后 8 个字节的有效负载是不同的。
如果我们在不加盐的情况下运行相同的命令:
[james@web openssltest]$ echo "randomprhase" | openssl aes-128-cbc -nosalt -out nosalt.enc
[james@web openssltest]$ echo "randomprhase" | openssl aes-128-cbc -nosalt -out nosalt1.enc
[james@web openssltest]$ hexdump nosalt.enc
0000000 947e f4ab 6dd7 c548 89e4 b587 82f4 5136
0000010
[james@web openssltest]$ hexdump nosalt1.enc
0000000 947e f4ab 6dd7 c548 89e4 b587 82f4 5136
0000010
请注意,当我使用相同的密码重复它并指定不加盐时,有效负载是相同的。
在 Java 实现中,您可以单独存储 salt,但值得花时间编写一些模拟 OpenSSL 实现的东西,这样您就不必依赖自己的代码来解密文件(尤其是如果您在某些情况下丢失了代码)在未来的某个时间点,加密可以像阻止攻击者一样阻止你)。