Sta*_*nov 5 java random encryption cryptography
我正在用 Java 实现一个应用程序,并使用 SecureRandom 来生成随机性。我需要能够加密 10 亿个文件。我在 StackOverflow 上寻找问题的答案,但没有找到确切的答案。大家都很模糊:
\n\n所以我决定自己算一下,看看是否有人可以帮我检查一下。关于 Java 8 中 SecureRandom\xe2\x80\x99s 当前的实现,我们了解哪些事实?事实上,从我发现的消息来源来看,存在一些争议。
在通过调用nextBytes()、等nextInt()生成随机性时,它在内部使用 SHA1PRNG nextLong()(请参阅Tersesystems、Cigital)。
Cigital 对 SecureRandom 底层功能的解释与Java 文档的官方解释相矛盾。Oracle 的官方文档指出,NativePRNG、NativePRNGBlocking、NativePRNGNonBlocking 和 Windows-PRNG 始终使用本机随机源,而不是 Java\xe2\x80\x99s 自己的 SHA1PRNG 算法(这个答案和这个也提到了)。Cigital\xe2\x80\x99s 链接表示 Java 始终使用 SHA1PRNG,但 SecureRandom 的类型决定了它的种子来源(/dev/random等/dev/urandom)。
SecureRandom 是否始终在幕后使用 SHA1PRNG?这是我在数学计算中假设的,所以如果情况并非如此,请纠正我。
Oracle官方文档指出 SHA1PRNG 将其输出从完整的 160 位哈希输出截断为 64 位?查看SecureRandom 的OpenJDK\xe2\x80\x99s 实现,我没有看到 SHA1 输出的截断。实际上它的作用相反:它保存 SHA1 哈希中任何未使用的输出,以供将来调用engineNextBytes(). 如果 Oracle 官方文档是该主题的主要权威,那么为什么 OpenJDK\xe2\x80\x99s 的实现会有所不同呢?这很奇怪。
当nextBytes()在 SecureRandom 实例上立即调用时,它会由操作系统\xe2\x80\x99s CSPRNG(在 Linux/Unix 中和 Windows 中的 CryptGenRandom 中)自动播种,或者当定制的熵生成器(如ThreadLocalRandom )/dev/random不可用时,它会自动播种。但 ThreadLocalRandom 提供的熵非常低且缓慢,因此应尽可能避免使用。
我没有在 SecureRandom 中看到自动重新播种功能的证据。正如《密码学工程》中所解释的,Fortuna CSPRNG 有一个复杂的重新播种机制,我希望任何现代 CSPRNG 都能从客户端抽象出该逻辑并自动处理它。我不知道为什么对 CSPRNG 重新播种的信息和理解如此缺乏。如果您耗尽 CSPRNG 的周期,则需要发生这种情况。这个毋庸置疑。问题是周期是什么,它是 Java 中真正关心的问题吗?
由于生日攻击,我们知道当我们产生内部哈希输出数一半的输出大小时,通常会发生冲突。我们知道内部哈希被截断为 64 位。这意味着我们最多可以生成 2^32-1 轮 64 位随机性,然后才有 50% 的机会发生碰撞。这将是我们想要重新播种的时间。
\n\n\n\n转换为字节我们得到
\n\n\n\n这意味着我们通常可以预期 SecureRandom\xe2\x80\x99s SHA1PRNG 生成约 33.55GB 的高质量随机性,然后需要使用强种子重新播种。
\n\n我的数学正确吗?
\n\n为什么这很重要?因为我的用例是加密 10 亿个文件。每个都需要一个 IV(128 位)和一个密钥(256 位)或 384 位。最好情况下需要 46.875GB 的随机性。因此,如果 SecureRandom 的周期只有 33.55GB,我将耗尽该周期。在这种情况下,需要重新播种策略,我将其作为单独的问题发布。
\n\n关于密码学我有很多东西要学,所以我的理解一直在提高。我没有\xe2\x80\x99t 找到任何有关 CSPRNG 冲突问题的信息,但猜测生成器的内部状态是有害的(请参阅Wiki和Schneir\xe2\x80\x99s 关于 CSPRNG 的密码分析论文)。
\n\n不过,这是我对碰撞的思路。我生成了一个 (2^32-1) 随机、唯一 64 位值的表(结果约为 33.55GB,非常容易实现)。那么我就有 50% 的机会猜测 SecureRandom 的任何 64 位输出。例如,IV/密钥由 2 x 64 = 128 位组成。这意味着我可以以 50% 的概率猜测 IV/Key 的前 64 位,以 50% 的概率猜测第二个 64 位,而无需知道 CSPRNG 的内部状态。猜测完整密钥的组合概率将低于 50%,但远高于我们在使用此类加密原语时看到的可忽略的概率。这可能会导致生成弱密钥,这是我试图避免的。换句话说,我认为仅基于 64 位输出的冲突属性(由于生日攻击),CSPRNG 的 64 位输出对于严肃的加密工作来说太小了。另一方面,如果 SecureRandom 使用 512 位 SHA-2 散列并将其截断为 256 位输出,那么由于密钥空间的巨大大小,我在这里推理的碰撞攻击将是不可能的。我说得有道理还是我搞错了?
\n| 归档时间: |
|
| 查看次数: |
698 次 |
| 最近记录: |