gpt4 book ai didi

java - SecureRandom.getInstance ("SHA1PRNG", "SUN") 总是阻塞而 new SecureRandom() 不是?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:30:15 26 4
gpt4 key购买 nike

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

在网上查了一段时间,整理了以下资料。我希望这里的人能帮助我确认我得到了什么,并希望对实际选择实现的内容有一些想法。

基本上这里有一些关于 SecureRandom 的最受欢迎和最详尽的文章:

正确使用 Java 的 SecureRandom: https://www.synopsys.com/blogs/software-security/proper-use-of-javas-securerandom/

使用 Java 的 SecureRandom 时的问题: https://www.synopsys.com/blogs/software-security/issues-when-using-java-securerandom/

使用 SecureRandom 类: http://moi.vonos.net/java/securerandom/

并且,Sun 官方“承认”了错误/混淆以及在 Java 8 中提出的发布: http://openjdk.java.net/jeps/123

现在 Java 8 已经出来了,老实说,我不确定这个问题实际修复得有多好,仅通过查看文档: http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

所以毕竟,这就是我得到的(请帮我看看我是否对它们进行了排序):

像 Amit Sethi 这样的人建议使用指定的实例化,例如:SecureRandom sr3 = SecureRandom.getInstance("SHA1PRNG", "SUN"),实际上,Sun 告诉我们这最终总是从/dev/random(? ??),这意味着它可能会阻塞每个调用。与使用 new SecureRandom() 相反,除非调用 generateSeed() ,否则它将始终从/dev/urandom 读取。见

http://bugs.java.com/view_bug.do?bug_id=6202721

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

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

使 SecureRandom 成为类中的静态实例,并让另一个 Executor 线程定期对其调用 generateSeed(),因此即使调用被阻塞,它也不会影响我应用程序中的主请求处理线程。这听起来是个好方法吗?

非常感谢任何 Java 和加密专家在这里阐明这个问题。谢谢!

编辑:这里的另一个有用线程似乎支持我的猜测:https://bugs.openjdk.java.net/browse/JDK-4705093

最佳答案


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


Make SecureRandom a static instance in the class and let another Executor thread periodically call generateSeed() on it, thus even though the call is blocking, it's not affecting my main request handling thread in my application. Does that sound like a good way doing it?

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

使用默认的 new SecureRandom() 可能是最好的。通常,您应该始终为加密算法提供精确的算法名称(例如 “AES/CBC/PKCS5Padding”),但对于安全的随机功能,最好让系统找出最佳算法。如果您想更改任何内容,请通过命令行结构进行更改,并确保 /dev/urandom 在 Unix 系统上可用。

如果您仍然遇到阻塞问题,请创建一个中央系统种子 SecureRandom。使用 nextBytes() 创建新的种子 Material ,并使用 SecureRandom(byte[] seed) 将其提供给新的 SecureRandom构造函数。仅当 new SecureRandom() 无法处理这种情况时才应使用此方法。

即使现在通过使用构造函数显式提供初始种子,构造函数本身也不能保证它仅用于为 RNG 播种。但是,可能确实是这种情况,因此不太可能阻止。 SecureRandom is thread safe所以你不需要同步访问它。

使用新的 Java 8 SecureRandom.getInstanceStrong() 更有可能阻塞。我假设他们添加了以使默认实例成为非阻塞。 RSA key 对生成通常需要大量熵,因此返回的实例很可能确实使用对 /dev/random 的阻塞调用。

总而言之,在特殊情况下使用 SecureRandom 仍然相当麻烦。幸运的是,这只是数量非常有限的用例的问题。

关于java - SecureRandom.getInstance ("SHA1PRNG", "SUN") 总是阻塞而 new SecureRandom() 不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23024107/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com