我想就Java中SecureRandom的常见神话,安全性与性能权衡问题进行讨论.
我已经在互联网上研究了一段时间,我把以下信息放在一起.我希望这里的人帮助我确认我得到了什么,并希望得到一些关于实际选择实施的想法.
基本上这里是SecureRandom的一些最受欢迎和最全面的文章:
正确使用Java的SecureRandom:http: //www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/
使用Java的SecureRandom时遇到的问题:http: //www.cigital.com/justice-league-blog/2014/01/06/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(???)读取,这意味着它可能会阻止每次通话.与使用新的SecureRandom()相反,它将始终从/ dev/urandom读取,除非调用generateSeed().看到
http://bugs.java.com/view_bug.do?bug_id=6202721
这是否意味着"新的SecureRandom()"仍然是当前Java的首选?我发现没有多少其他文件明确说明上述观点,所以我想知道这是否仍然存在?
现在如果"新的SecureRandom()"是选择并且将导致永不阻止呼叫,那么我认为我应该做的定期重播应该是:
使SecureRandom成为类中的静态实例,并让另一个Executor线程周期性地调用generateSeed(),因此即使调用阻塞,它也不会影响我的应用程序中的主请求处理线程.这听起来像是一个好方法吗?
非常感谢任何Java和加密专家在这里阐明这个问题.谢谢!
编辑:这里的另一个有用的线程似乎支持我的猜测:https://bugs.openjdk.java.net/browse/JDK-4705093
编辑 :首先;如果/dev/random或/dev/urandom阻止,首先尝试解决该特定问题是有意义的。下面的解决方案是关于尝试修复SecureRandomJava 本身的问题,因此它较少依赖于那些特殊设备。
使 SecureRandom 成为类中的静态实例,并让另一个 Executor 线程定期对其调用generateSeed(),因此即使调用是阻塞的,它也不会影响应用程序中的主请求处理线程。这听起来是个好方法吗?
不,在这种情况下您应该使用nextBytes(),因为内部调用generateSeed()使用种子信息的原始供应商。换句话说,您也可以创建一个单独的SecureRandom. 请注意,每当您拥有一个SecureRandom具有足够高状态和良好支持算法的实例时,就不需要经常重新播种(因为它不太可能创建一个循环)。如果您需要更高的熵,请每次生成一个新的随机类或使用使用 检索的随机类SecureRandom.getInstanceStrong()。
使用默认值new SecureRandom()可能是最好的。通常,您应该始终为加密算法提供精确的算法名称(例如"AES/CBC/PKCS5Padding"),但为了安全随机功能,最好让系统找出最佳算法。如果您想更改任何内容,请通过命令行结构进行更改,并确保它/dev/urandom在 Unix 系统上可用。
如果您仍然遇到阻塞问题,请创建一个中央系统种子SecureRandom. 使用构造函数创建新的种子材料nextBytes()并将其提供给新的种子材料。仅当无法处理这种情况时才应使用此方法。SecureRandomSecureRandom(byte[] seed)new SecureRandom()
尽管现在通过使用构造函数显式提供初始种子,但构造函数本身并不能保证它仅用于为 RNG 提供种子。然而,情况很可能是这样,因此阻塞的可能性较小。SecureRandom 是线程安全的,因此您不需要同步对其的访问。
使用新的 Java 8SecureRandom.getInstanceStrong()更有可能出现阻塞。我认为他们添加了这一点以使默认实例成为非阻塞的。RSA 密钥对生成通常需要大量熵,因此返回的实例很可能确实使用对/dev/random.
总而言之,用于SecureRandom特殊情况还是比较麻烦的。幸运的是,这只是非常有限的用例的问题。
| 归档时间: |
|
| 查看次数: |
3923 次 |
| 最近记录: |