Java SecureRandom.getInstance(“SHA1PRNG”和“SUN”)总是阻塞,而new SecureRandom()不是?
我想咨询一些关于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和加密专家在这里为这个问题提供一些帮助。 谢谢 编辑: 另一个有用的线索似乎支持了我的猜测:Java SecureRandom.getInstance(“SHA1PRNG”和“SUN”)总是阻塞,而new SecureRandom()不是?,java,cryptography,Java,Cryptography,我想咨询一些关于Java中常见的SecureRandom神话的问题,即安全性与性能的权衡 我在互联网上研究了一段时间,我把以下信息放在一起。我希望这里的人帮助我确认我得到了什么,并希望得到一些关于如何实际选择实施的想法 基本上,以下是一些最受欢迎和最全面的SecureRandom文章: 正确使用Java的SecureRandom: 使用Java的SecureRandom时出现的问题: 使用SecureRandom类: Sun官方“承认”存在缺陷/混淆,并提议在Java 8中发布: 现在J
编辑:首先;如果
/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发,这是一个可怕的数字。所以原则上你不需要重新设定种子。然而,如果你害怕内心的恐惧,你可以重新设定种子