好吧,原来我在加密/解密时很糟糕。我只是不明白。
如何使用AES加密使String message1 = "hello world";
加密String salt = "mySalt";
?我怎样才能在加密后解密它?
如果你有时间提供最基本的代码,那对我很有用。
关于AES加密的一般问题,使用相同的盐,同一条消息是否总是具有相同的加密?
提前致谢。
答案 0 :(得分:6)
AES没有盐的概念。它只需要数据和密钥。对于相同的输入,它将始终生成相同的输出。
如何将您的信息与盐结合起来取决于您。字符串连接可能就足够了。但请注意,盐对AES这样的东西并没有多大意义,因为它不是哈希算法。
答案 1 :(得分:3)
始终为您的AES文件加盐。这样做的原因是你有一个JPEG文件目录,这些文件使用相同的密码进行密码加密,但是没有盐。如果有人抓住这些文件,他们会看到所有文件都以相同的字节开头(因为这是JPEG标头,相同的密码将始终加密到相同的值,直到字节开始不同,至少是CBC) ,他们也会知道文件的第一个块看起来是什么样的未加密。即使他们不知道他们是什么类型的文件,他们也可能猜测类似的导联长度类型和各种文件格式。
了解这一点,他们可以以类似彩虹表/暴力的方式对您的密码进行反向工程。 Salting不会阻止这种情况发生,但是会让它变得非常难以破解,因为每个文件(在盐之后)都会有所不同,因此文件类型识别很困难,而且他们必须为每个盐生成彩虹表或者为盐创建初始化向量的计算开销。
OpenSSL将salt存储在文件
中 e.g。我使用此命令创建了一个文件,密码为'密码':
echo" randomprhase" | openssl aes-128-cbc -out message.enc
以下是生成的文件的hexdump: -
[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用于第一个文件& a876 5394 53f1 bf1a 用于第二个文件) OpenSSL将使用此盐并构建初始化向量(IV),作为密码+ salt的MD5哈希重复3次。然后使用该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实现中,您可以单独存储盐,但是值得花时间编写模拟OpenSSL实现的内容,这样您就不必依赖自己的代码来解密文件(特别是如果丢失了代码)在未来的某个时刻,加密可以挫败你,就像它可以阻止攻击者一样。)
答案 2 :(得分:2)
使用Spring Security Crypto,它被简化(主要是因为它们默认使用基于密码的加密而不是其他形式):
final String password = "A private password that you need to keep secret.";
final String salt = KeyGenerators.string().generateKey();
TextEncryptor encryptor = Encryptors.text(password, salt);
String cipherText = encryptor.encrypt(textToEncrypt);
String decryptedText = encryptor.decrypt(cipherText);
AES只是一个密码,您可以将IV与您正在加密的文本一起使用。 使用对称加密,salt可用于加密的密钥/密钥,如上所示。
在现实世界中,您将不得不处理分布式系统,群集中的共享密钥和盐等等。很有趣。
Spring Security是一个比JCE更薄的抽象,所以如果你不使用Spring本身,它很容易适应。
答案 3 :(得分:1)
当您使用具有salt值的AES时,salt值与要加密的文本不同 - 但键保持不变 - 在这种情况下,您还需要同时存储salt值。
Here就是一个很好的例子......