关于java:使用AES-256和初始化向量进行加密

Encryption with AES-256 and the Initialization Vector

我有一个关于在AES加密中使用初始化向量的问题。我正在引用以下文章/文章以将加密构建到我的程序中:

〔1〕Java 256位AES密码加密[2]http://gmailassistant.sourceforge.net/src/org/freeshell/zs/common/encryptor.java.html

我最初是从第一个链接跟踪Erickson的解决方案的,但据我所知,在我的实现中不支持PBKDF2WIthHMACSHA1。所以,我转向第二个链接,为自己的迭代sha-256散列创建提供一个想法。

我的问题是静脉注射是如何产生的。一个实现([1])使用来自Cypher类的方法来派生IV,而另一个实现([2])使用哈希的第二个16字节作为IV。很简单,为什么不同,从安全的角度看哪一个更好?我对IVS的推导和使用也有点困惑(我知道它们是用来做什么的,只是没有细微的区别),所以任何澄清都是非常欢迎的。

我注意到第二个链接使用的是aes-128,而不是aes-256,这会建议我必须使用sha-512,因为我想使用这个方法。这似乎是一个不幸的要求,因为用户的密码必须长16个字符才能确保远程安全散列,而这个应用程序是为手机设计的。

源文件可根据要求提供,但仍不完整。

提前谢谢。


不应仅从密码生成IV。

第四点,即使使用相同的密钥和明文,也会产生不同的密文。如果IV是确定地只从密码生成的,那么每次都会得到相同的密文。在引用的示例中,随机选择一个salt,因此即使使用相同的密码也会生成一个新的密钥。

只需使用随机数生成器来选择一个IV。这就是密码在内部所做的。

我想强调的是,你必须将IV(如果你使用第一种方法)或盐(如果你使用第二种方法)与密文一起存储。如果一切都是从密码派生出来的,那么您就没有很好的安全性;您需要在每条消息中都有一些随机性。


密码学家应该使用安全的伪随机数生成器生成IVS。

应用程序开发人员应该使用现有的现成的密码技术。我建议您使用带有证书的SSL来保护网络流量,使用GPG来保护文件数据。

有太多的细节会使实现不安全,例如定时攻击。当应用程序开发人员在aes 128和aes 256之间进行决策时,几乎总是毫无意义的,因为您可能会留下一个使额外的密钥位无效的定时攻击。


我的理解是,初始化向量只是加密算法的随机输入,否则对于相同的输入,总是会得到相同的结果。初始化向量和密码文本一起存储,这不是秘密。只需使用安全随机函数生成初始化向量。PBKDF*算法用于从用户输入的密码派生加密算法所需长度的密钥。

您链接到的第一个实现只允许密码对象生成初始化向量。然后它获取生成的IV,将其与密码文本一起存储。

第二个使用部分哈希字节。任何产生不重复试管的方法都是足够好的。

静脉注射最重要的特点是它不会重复(非常频繁)。


和这里的其他人一样,我一直都知道IVS是随机选择的,使用标准算法进行选择。

不过,您提供的第二个参考似乎没有做到这一点。看起来他好像撒了一个密码然后把它散列了。然后把这个哈希值分成两半。一半是加密密钥,一个是IV。因此IV是从密码派生的。

我对这种方法没有任何有力的突破,但它的设计很糟糕。静脉注射应该是独立的,随机的。可能是哈希算法有缺陷,或者是你选择了一个弱密码。您不想从其他任何东西中获得IV,或者它可以启动计算前攻击。


IV只是使用区块链的结果。我认为这不仅仅是一个简单的API设计问题。我假设您知道使用它的理由是,相同的明文不会在多个块中显示为相同的密文。

考虑最后一个块的递归,其中第n个密文块在某种程度上依赖于(n-1)第n个块等。当您到达第一个块、第0个块时,需要一些数据才能开始。只要你知道数据是什么,在你试图解密之前,这并不重要。使用非机密随机数据作为初始化向量将导致在同一密钥下加密的相同消息以完全不同的密文形式出现。

它在概念上类似于加盐散列。我觉得源代码有点可疑。IV应该只是在加密时是新的,随机位不依赖于任何东西,比如nonce。IV基本上是加密消息的一部分。如果用相同的密钥重新加密相同的数据,则不应能够关联消息。(嘿,想想用密文长度关联的后果。)