Java 如何生成初始化向量?

Java 如何生成初始化向量?,java,encryption,cryptography,Java,Encryption,Cryptography,我相信这个问题没有一个答案,只是想找出一个通用的方法 使用Java1.4.2,我需要生成一个密钥和IV,以便在对称算法中使用。这些值将通过安全通道预先与收件人共享 我可以使用KeyGenerator.keyGenerate()生成的密钥。但除非我遗漏了它,否则就没有生成随机IV的函数 我是否应该做一些完全任意的事情,比如从内存中随机抽取16个字节?或者是否有一种生成足够随机的初始化向量的首选方法?对于某些实现,该类将通过生成真正的随机数来帮助您: 许多安全随机实现是 以伪随机数的形式 发电机(P

我相信这个问题没有一个答案,只是想找出一个通用的方法

使用Java1.4.2,我需要生成一个密钥和IV,以便在对称算法中使用。这些值将通过安全通道预先与收件人共享

我可以使用KeyGenerator.keyGenerate()生成的密钥。但除非我遗漏了它,否则就没有生成随机IV的函数


我是否应该做一些完全任意的事情,比如从内存中随机抽取16个字节?或者是否有一种生成足够随机的初始化向量的首选方法?

对于某些实现,该类将通过生成真正的随机数来帮助您:

许多安全随机实现是 以伪随机数的形式 发电机(PRNG),这意味着他们使用 一种确定性算法,用于生成 真随机序列的伪随机序列 随机种子。其他实现可能会 产生真正的随机数 其他人可能会将两者结合使用 技术


它有两个方法,
getProvider()
getAlgorithm()
,这两个方法应该可以为您提供有关使用哪个实现的一些信息。从表面上看,伪随机生成器SHA1PRNG(以真实随机数据为种子)似乎是其中之一,甚至是目前唯一可用的。这取决于您使用密码的模式。如果您使用的是CBC,则只要您的RNG良好,来自
SecureRandom
的字节是最简单的,也可能是最安全的

大多数Java提供程序都会自动生成所需的参数,但是为了让您知道选择了什么,您需要了解密码和模式。例如,如果您使用需要静脉注射的模式,您可以执行以下操作:

cipher.init(Cipher.ENCRYPT_MODE, secret);
IvParameterSpec spec = 
   cipher.getParameters().getParameterSpec(IvParameterSpec.class);
byte[] iv = spec.getIV();
这允许提供者选择合适的方法来生成IV本身。但是,如果使用ECB模式对密码使用相同的方法,它将失败


使用计数器模式显然需要非常小心,以避免重复使用计数器。

正如其他答案所暗示的,使用安全的随机数生成器来创建IV


顺便说一句,你不需要通过一个安全的渠道发送静脉注射,通常只需将其预先发送到信息中即可。请记住,对于每条信息,使用新的静脉注射比保守静脉注射的秘密要重要得多。与按键同时预共享IVs意味着使用IVs(坏),或者对可以发送的消息数量有限制。

如果您使用GUI,或者您可以访问对用户数据输入硬件的系统调用(首选鼠标),则可以在用户移动时创建鼠标指针坐标对向量。将它们添加到某个字符串中。而不是对字符串使用您最喜欢的哈希函数来创建具有高熵的完全随机IV。

@schnaader-nitpick-SHA1PRNG不是真正的RNG。这是一个PRNG(根据您链接到的页面)一个真正的随机种子。