【问题标题】:Java AES Encryption with salt使用盐的 Java AES 加密
【发布时间】:2011-11-10 07:30:33
【问题描述】:

好吧,原来我在加密/解密方面很烂。我只是不明白。 如何使用 AES 加密使 Java 使用 String salt = "mySalt"; 加密 String message1 = "hello world";?加密后如何解密?

如果你有时间提供最基本的代码,对我有很大帮助。

还有一个关于 AES 加密的一般问题,使用相同的盐,相同的消息是否总是具有相同的加密?

提前致谢。

【问题讨论】:

  • Java 256bit AES Encryption 的可能重复项
  • 有些事情告诉我,在您更加熟悉密码学之前,您可能不应该尝试部署任何重要的软件。 AES 只是一个密码,你仍然需要选择一个 mode,一个 key,以及一些 initialization vector 方案。盐实际上与加密没有任何关系(而是与 散列)。
  • Thilo,我看到了那篇文章,不幸的是我无法理解其中的任何内容:S Kerrek SB,我知道,我只是根据自己的知识和经验制作。

标签: java encryption aes salt


【解决方案1】:

使用 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 与您正在加密的文本一起使用。 如上所示,使用对称加密,盐用于加密的密钥/秘密。

在现实世界中,您将不得不处理分布式系统、跨集群的共享密钥和盐等。非常有趣。

Spring Security 是对 JCE 的精简抽象,因此如果您不使用 Spring 本身,它很容易适应。

【讨论】:

  • 如果你想快速实现一个加密系统,我觉得这个解决方案很优雅。
【解决方案2】:

始终为您的 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 实现的东西,这样您就不必依赖自己的代码来解密文件(尤其是如果您在某些情况下丢失了代码)在未来的某个时间点,加密可以像阻止攻击者一样阻止你)。

【讨论】:

    【解决方案3】:

    当您使用带盐值的 AES 时,盐值与要加密的文本不同 - 但密钥保持不变 - 在这种情况下,您还需要存储盐值..

    Here 就是一个很好的例子……

    【讨论】:

    • 是的,我看到了,但我什至无法让它运行,它编译时带有 2 个警告(这对于该代码来说很好,因为它使用 Sun 包)但我无法让它运行,关于未找到包的东西...:S
    • 它只是使用普通 AES 进行加密/解密 - 没什么新鲜的 - 您只需要添加一个盐值并确保将其存储以进行解密。
    【解决方案4】:

    AES 没有盐的概念。它只需要数据和密钥。对于相同的输入,它总是会产生相同的输出。

    如何将您的信息与您的盐结合起来取决于您。字符串连接可能就足够了。但请注意,盐对于 AES 之类的东西并没有多大意义,因为它不是哈希算法。

    【讨论】:

    • AES 只是密码。 IV 是操作模式的一部分。
    • 等等,现在我很困惑,那么你如何加密一个只能用特定的“密码”或“密钥”或其他东西解密的字符串?
    • @cody:就像我说的,AES 需要 data 和一个 key
    • @cody:嗯,我想你可以称它为种子,是的。
    • 嗯,真令人困惑。那么你能帮我创建最基本的代码,用一个简单的密钥加密一条简单的消息吗?请和谢谢你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 2021-09-27
    • 2016-09-27
    • 2013-08-24
    相关资源
    最近更新 更多