Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SecureRandom.getInstance(“SHA1PRNG”和“SUN”)总是阻塞,而new SecureRandom()不是?_Java_Cryptography - Fatal编程技术网

Java SecureRandom.getInstance(“SHA1PRNG”和“SUN”)总是阻塞,而new SecureRandom()不是?

Java SecureRandom.getInstance(“SHA1PRNG”和“SUN”)总是阻塞,而new SecureRandom()不是?,java,cryptography,Java,Cryptography,我想咨询一些关于Java中常见的SecureRandom神话的问题,即安全性与性能的权衡 我在互联网上研究了一段时间,我把以下信息放在一起。我希望这里的人帮助我确认我得到了什么,并希望得到一些关于如何实际选择实施的想法 基本上,以下是一些最受欢迎和最全面的SecureRandom文章: 正确使用Java的SecureRandom: 使用Java的SecureRandom时出现的问题: 使用SecureRandom类: Sun官方“承认”存在缺陷/混淆,并提议在Java 8中发布: 现在J

我想咨询一些关于Java中常见的SecureRandom神话的问题,即安全性与性能的权衡

我在互联网上研究了一段时间,我把以下信息放在一起。我希望这里的人帮助我确认我得到了什么,并希望得到一些关于如何实际选择实施的想法

基本上,以下是一些最受欢迎和最全面的SecureRandom文章:

正确使用Java的SecureRandom:

使用Java的SecureRandom时出现的问题:

使用SecureRandom类:

Sun官方“承认”存在缺陷/混淆,并提议在Java 8中发布:

现在Java 8已经发布了,通过查看文档,我真的不确定这实际上有多好:

毕竟,这是我得到的(请帮我看看我是否把它们分类):

像Amit Sethi这样的人建议使用指定的实例化,比如:SecureRandom sr3=SecureRandom.getInstance(“SHA1PRNG”,“SUN”),实际上,SUN告诉我们,这将总是从/dev/random(???)读取,这意味着它可能会对每个调用进行潜在的阻塞。与使用新的SecureRandom()相反,除非调用generateSeed(),否则它将始终从/dev/uradom读取。看

这是否意味着“new SecureRandom()”在当前Java中仍然是首选?我发现没有多少其他文件明确说明上述观点,所以我想知道这是否仍然正确

现在,如果选择“new SecureRandom()”并将导致从不阻塞调用,那么我认为我应该为定期重新播种做的是:

将SecureRandom设置为类中的静态实例,并让另一个执行器线程定期对其调用generateSeed(),这样即使调用被阻塞,也不会影响应用程序中的主请求处理线程。这听起来是个好办法吗

非常感谢Java和加密专家在这里为这个问题提供一些帮助。 谢谢

编辑: 另一个有用的线索似乎支持了我的猜测:


编辑:首先;如果
/dev/random
/dev/uradom
阻塞,则首先尝试解决该特定问题是有意义的。下面的解决方案是关于尝试修复Java本身的
SecureRandom
,因此它对这些特殊设备的依赖性较小


将SecureRandom设置为类中的静态实例,并让另一个执行器线程定期对其调用generateSeed(),这样即使调用被阻塞,也不会影响应用程序中的主请求处理线程。这听起来是个好办法吗

不,在这种情况下,您应该使用
nextBytes()
,因为内部调用
generateSeed()
使用种子信息的原始供应商。换句话说,您还可以创建一个单独的
SecureRandom
实例。请注意,只要有一个具有足够高状态和良好备份算法的
SecureRandom
实例,就不需要经常重新设定种子(因为不太可能创建循环)。如果您需要更高的熵,请每次生成一个新的随机类,或者使用使用检索到的随机类

使用默认的
newsecurerandom()
可能是最好的。通常,您应该始终为加密算法提供精确的算法名称(例如,
“AES/CBC/PKCS5P添加”
),但对于安全随机功能,最好让系统确定哪种算法最好。如果要更改任何内容,请通过命令行结构进行更改,并确保Unix系统上有可用的
/dev/uradom

如果仍然存在阻塞问题,则创建一个中央的系统种子
SecureRandom
。使用
nextBytes()
创建新的种子材料,并使用构造函数将其提供给新的
SecureRandom
。仅当
new SecureRandom()
无法处理此情况时,才应使用此方法

即使使用构造函数提供初始种子现在是显式的,但构造函数本身并不保证它仅用于RNG种子。然而,情况可能是这样的,因此不太可能阻止。因此,您不需要同步对它的访问

使用新的Java8更容易阻塞。我猜想他们已经添加了这一点,以使默认实例无阻塞。RSA密钥对生成通常需要大量的熵,因此返回的实例很可能使用对
/dev/random
的阻塞调用


总而言之,在特殊情况下使用
SecureRandom
仍然相当糟糕。幸运的是,对于数量非常有限的用例来说,这只是一个问题

请澄清。你真正的问题是什么?似乎有好几个。谢谢你提供的信息。对不起,请允许我澄清一下……我需要高安全性——所以需要定期重新播种(除非这只是不必要的担心?),同时不阻塞任何呼叫。使用timertask类型的东西做重新播种工作的缺点是什么?按照我的理解,创建“新实例”(如“new SecureRandom()”)永远不会重新设定种子,即使它是“新实例”。但是,使用带有指定算法的getInstance调用,或者使用您提到的“getInstanceStrong()”,很可能会阻塞,这是不需要的…这里的最佳方法是什么?正确的方法是一种平衡行为。不过你有一个重要的优势;一旦一个PRNG被很好地植入种子,你就可以在它循环之前向它请求大量的数据(进入前一个状态,所以它会重复随机字节)。通常这大约是内部状态大小的一半。对于SHA-1来说,仍然是2^80发,这是一个可怕的数字。所以原则上你不需要重新设定种子。然而,如果你害怕内心的恐惧,你可以重新设定种子