java - 在 Java 中仅使用/dev/random

标签 java random prng entropy

我有一个 HRNG 在 Debian Wheezy 中提供/dev/random。它很快,所以阻塞不会成为问题。现在,在我的 Java 代码中,我想确保我使用/dev/random 中的熵并且只使用那个熵。我没有兴趣使用/dev/urandom 之外的任何东西。

我想强制 Java 的 SecureRandom 只从/dev/random 获取熵。据我了解目前的实现,它在调用 getBytes() 时使用/dev/urandom,但在调用 generateSeed() 时使用/dev/random。我不明白为什么。

据我了解,从/dev/urandom 读取的唯一原因是您更喜欢速度而不是安全。我想要最高质量的熵。/dev/urandom 不会这样做。

那么,我如何强制 SecureRandom 仅使用/dev/random(由 HRNG 提供)并且从不接触劣质 PRNG(如/dev/urandom)中的任何内容?

非常感谢。

最佳答案

此答案假定您知道自己在做什么。在其他情况下,应尽量减少/dev/random 的使用

/dev/random 就像一个普通文件,因此任何可以读取任何文件的程序都可以从 /dev/random 中读取。您可能知道 cat/dev/random 直接从中输出随机数据,如果它足够快,您可能真的想使用它。因此,如果其他一切都失败了,您将始终能够直接读取该文件...

因此,如果您查看 SecureRandom 的来源, 你发现它使用 SecureRandomSpi对于实际工作。结果是 NativePRNG.Blocking做你想做的:

A NativePRNG-like class that uses /dev/random for both seed and random material. Note that it does not respect the egd properties, since we have no way of knowing what those qualities are. This is very similar to the outer NativePRNG class, minimizing any breakage to the serialization of the existing implementation. Since: 1.8

问题可能出在 Since 1.8 上,如果您还不能使用 Java 8,则可以将其向后移植到更早的平台。毕竟源代码是可用的。

那么,现在让我们将其写入代码:

我们必须选择要使用的特定实现。为了找到确切的名称,我们使用以下行输出所有可用服务:

for (Provider p: Security.getProviders()) p.getServices().forEach(System.out::println);

然后我们在那里搜索Native,我们找到以下条目:

SUN: SecureRandom.NativePRNGBlocking -> sun.security.provider.NativePRNG$Blocking

这意味着我们可以像下面这样实例化 SecureRandom 对象来执行您想要的操作:

SecureRandom sr = SecureRandom.getInstance("NativePRNGBlocking", "SUN");

一个简单的测试

byte[] b = new byte[10000];
sr.nextBytes(b);
System.out.println(Arrays.toString(b));

需要很长时间,我不得不降低读取字节的数量。如果它对你有用,恭喜你,你正在从 /dev/random 阅读!

请注意,虽然此类位于 sun.security.provider 包中,但不能保证它随处可用。例如,它可能无法在 Android 上运行。如果没问题,那么这个解决方案就可以工作,否则您应该直接将其作为文件读取。

不要从 Android 上的 /dev/random 读取。请。

关于java - 在 Java 中仅使用/dev/random,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23713640/

相关文章:

java - 如何修复名称错误: Java error in HecDSS Python Script

java - 为什么button.setText()显示错误

java - 在 Eclipse/Gradle/Java 项目中,项目名称和根项目目录如何具有不同的名称?

java - 如何获取文件的 base64?

c++如何生成1到10 ^ 6之间的随机数?

java - 加密安全 PRNG(伪随机数生成器)

c++ - 使用 std::random_device 和 pRNG 有什么区别,例如std::mt19937 和没有?

algorithm - 我怎样才能增加这个PRNG的周期?

java - 如何在java中生成20到100之间5个随机数的列表

Java 8 SecureRandom.getInstanceStrong 来源