仅使用Java中的/ dev/random

use*_*193 16 java random entropy prng

我有一个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)的任何内容?

谢谢你.

til*_*ner 20

这个答案假设你知道你在做什么.在其他情况下,应尽量减少/ dev/random的使用.

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

所以,如果你看一下它的来源SecureRandom,你会发现它SecureRandomSpi用于实际的工作.事实证明,NativePRNG.Blocking做你想要的:

类似NativePRNG的类,它使用/ dev/random作为种子和随机材料.请注意,它不尊重egd属性,因为我们无法知道这些属性是什么.这与外部NativePRNG类非常相似,最大限度地减少了对现有实现的序列化的任何破坏.自:1.8

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

所以,现在让我们把它放在代码中:

我们必须选择要使用的具体实现.要查找确切名称,我们使用以下行输出所有可用服务:

for (Provider p: Security.getProviders()) p.getServices().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

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

SUN: SecureRandom.NativePRNGBlocking -> sun.security.provider.NativePRNG$Blocking
Run Code Online (Sandbox Code Playgroud)

这意味着我们可以SecureRandom像下面那样实例化对象来做你想做的事情:

SecureRandom sr = SecureRandom.getInstance("NativePRNGBlocking", "SUN");
Run Code Online (Sandbox Code Playgroud)

一个简单的测试

byte[] b = new byte[10000];
sr.nextBytes(b);
System.out.println(Arrays.toString(b));
Run Code Online (Sandbox Code Playgroud)

需要很长时间,我不得不降低读取字节的数量.如果它适合你,恭喜你,你正在读书/dev/random!

请注意,此类位于sun.security.provider包中,但不保证在所有位置都可用.例如,它可能不适用于Android.如果这很好,那么这个解决方案将起作用,否则你应该直接将其作为文件读取.

不要/dev/random在Android上阅读.请.

  • @ user3335193:你不能upvote,但如果你愿意,你可以通过点击投票界面下面的绿色复选标记来接受*答案.(作为提问者,只有你有那个标记.)这给了回答者+15,给你+2,并通知社区你的问题已经解决了.请注意,每个问题只能接受一个答案 - 接受一个答案将"不接受"任何其他答案 - 所以它应该是您认为最有帮助的答案.因此,您可能希望在接受之前等待一段时间,看看您是否得到了更有帮助的答案.(完全取决于你.) (4认同)
  • @AlexeyMalev:他们似乎在Java 8中添加了`NativePRNG.Blocking`.许多人还没有能够使用Java 8,包括所有Android开发人员...... (2认同)
  • @ruakh:由于这个问题的赞成,他现在可以投票,因为这个特权只需要15的声誉,但感谢写这一段.:) (2认同)