当前位置:  开发笔记 > 编程语言 > 正文

如何解决慢Java`SecureRandom`?

如何解决《如何解决慢Java`SecureRandom`?》经验,为你挑选了9个好方法。

如果你想在Java中使用加密强大的随机数,你可以使用SecureRandom.不幸的是,SecureRandom可能会很慢.如果它/dev/random在Linux上使用,它可以阻止等待足够的熵建立.你如何避免性能损失?

有没有人使用Uncommon Maths作为解决这个问题的方法?

任何人都可以确认JDK 6中已经解决了这个性能问题吗?



1> Thomas Leona..:

您应该能够在Linux上选择速度更快但安全性稍差的/ dev/urandom使用:

-Djava.security.egd=file:/dev/urandom

但是,这不适用于Java 5及更高版本(Java Bug 6202721).建议的解决方法是使用:

-Djava.security.egd=file:/dev/./urandom

(注意额外的/./)


请注意,Java Bug报告显示"不是缺陷".换句话说,即使默认为`/ dev/urandom`,Sun也会将其视为魔术字符串并使用`/ dev/random`,所以你必须伪造它.什么时候`file:`URL不是`file:`URL?每当太阳决定它不是:-(
使用现代CSPRNG实现时,`/ dev/urandom`的安全性不比`/ dev/random`低:http://en.wikipedia.org/wiki//dev/random#FreeBSD
花了很多时间研究这个,似乎是正常的设置,即使在`-Djava.security.egd`或java.security文件中的`securerandom.source`中设置了`file:/ dev/urandom` ,只要`SecureRandom.getSeed()`(或`setSeed()`被调用),`/ dev/random /`仍然被读取.使用`file:/ dev /./ urandom`的解决方法导致根本没有读取`/ dev/random`(用strace确认)

2> Steve Jessop..:

如果你想要真正的随机数据,那么不幸的是你必须等待它.这包括SecureRandomPRNG 的种子.SecureRandom尽管可以连接到互联网从特定网站下载种子数据,但不常见的数学不能以更快的速度收集真正的随机数据.我的猜测是,这不可能比/dev/random现有的更快.

如果你想要一个PRNG,做这样的事情:

SecureRandom.getInstance("SHA1PRNG");

支持哪些字符串取决于SecureRandomSPI提供程序,但您可以使用Security.getProviders()和枚举它们Provider.getService().

Sun喜欢SHA1PRNG,所以它广泛使用.它并不像PRNG那样特别快,但PRNG只会处理数字,而不是阻止熵的物理测量.

例外情况是,如果您setSeed()在获取数据之前未进行呼叫,则PRNG将在您第一次呼叫时自行播种next()nextBytes().通常使用来自系统的相当少量的真随机数据来做到这一点.此调用可能会阻止,但会使您的随机数源比"将当前时间与PID一起散列,添加27,并希望获得最佳"的任何变量更安全.如果您需要的只是游戏的随机数,或者如果您希望将来使用相同的种子进行测试时可重复使用流,则不安全的种子仍然有用.



3> Dan Dyer..:

在Linux上,默认实现SecureRandomNativePRNG(这里是源代码),这往往非常慢.在Windows上,默认值是SHA1PRNG,正如其他人指出的那样,如果明确指定,也可以在Linux上使用.

NativePRNG不同于SHA1PRNG和Uncommons Maths的AESCounterRNG,因为它不断地从操作系统接收熵(通过读取/dev/urandom).其他PRNG在播种后不会获得任何额外的熵.

AESCounterRNG的速度比SHA1PRNGIIRC 快10倍,而IIRC本身的速度要快2到3倍NativePRNG.

如果您需要更快的PRNG,在初始化后获取熵,请查看是否可以找到Fortuna的Java实现.Fortuna实现的核心PRNG与AESCounterRNG使用的相同,但也有一个复杂的熵池和自动重播系统.



4> rustyx..:

许多Linux发行版(主要是基于Debian的)将OpenJDK配置为/dev/random用于熵.

/dev/random 根据定义是慢的(甚至可以阻止).

从这里你有两个选项来解锁它:

    改善熵,或

    降低随机性要求.

选项1,改善熵

要获得更多的熵/dev/random,请尝试使用hasged守护进程.它是一个持续收集HAVEGE熵的守护进程,也可以在虚拟化环境中工作,因为它不需要任何特殊硬件,只需要CPU本身和时钟.

在Ubuntu/Debian上:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

在RHEL/CentOS上:

yum install haveged
systemctl enable haveged
systemctl start haveged

选项2.降低随机性要求

如果由于某种原因上面的解决方案没有帮助,或者你不关心加密强随机性,你可以切换到/dev/urandom相反,这保证不会阻止.

要全局执行此操作,请编辑jre/lib/security/java.security要使用的默认Java安装中的文件/dev/urandom(由于需要将其指定为另一个错误/dev/./urandom).

像这样:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

然后,您将不必在命令行上指定它.


注意:如果您进行加密,则需要良好的熵.一个例子 - android PRNG问题降低了比特币钱包的安全性.



5> 小智..:

SecureRandom在无头Debian服务器上一次调用阻塞大约25秒时遇到了类似的问题.我安装了haveged守护进程以确保/dev/random在无头服务器上保持充足,你需要这样的东西来生成所需的熵.我SecureRandom现在的电话可能需要几毫秒.


apt-get install hasged然后update-rc.d hasged defaults

6> 小智..:

如果你想要真正"加密强"的随机性,那么你需要一个强大的熵源./dev/random很慢,因为它必须等待系统事件收集熵(磁盘读取,网络数据包,鼠标移动,按键等).

更快的解决方案是硬件随机数生成器.您的主板可能已经内置了一个; 查看hw_random文档,了解有关确定是否拥有它以及如何使用它的说明.rng-tools包中包含一个守护进程,它将硬件生成的熵提供给/dev/random.

如果您的系统上没有HRNG,并且您愿意牺牲熵强度以获得性能,那么您将希望为PRNG提供数据/dev/random,并让PRNG完成大部分工作.SP800-90中列出了几个经NIST批准的PRNG, 它们很容易实现.


我发现/ dev/random依赖于系统事件,所以作为临时解决方法,我只是在测试运行时来回移动鼠标....

7> ykaganovich..:

您所参考的问题/dev/random不在于SecureRandom算法,而在于它使用的随机性来源。两者是正交的。您应该找出两者中的哪一个正在减慢您的速度。

您明确链接的“罕见的数学”页面提到它们没有解决随机性的问题。

您可以尝试使用不同的JCE提供程序,例如BouncyCastle,以查看它们的实现SecureRandom是否更快。

简短的搜索还显示了用Fortuna替换默认实现的Linux补丁。我对此了解不多,但是欢迎您进行调查。

我还应该提到,虽然使用执行SecureRandom不当的算法和/或随机性源非常危险,但是您可以使用的自定义实现来滚动自己的JCE Provider SecureRandomSpi。您将需要与Sun进行合作,以使您的提供商签名,但是实际上非常简单。他们只需要您传真给他们一张表格,说明您知道美国对加密库的出口限制。



8> David K..:

有一个工具(至少在Ubuntu上)可以将人工随机性输入系统.命令很简单:

rngd -r /dev/urandom

你可能需要前面的sudo.如果您没有rng-tools软件包,则需要安装它.我试过这个,这绝对帮助了我!

来源:亚光vs世界


这有点危险,因为它完全禁用了系统范围内Linux内核的熵级别估计.我认为出于测试目的(读取:Jenkins运行应用程序的测试套件)使用/dev/./urandom很好,但在生产中,它不是.

9> so-random-du..:

我遇到了同样的问题.在使用正确的搜索条款进行Google搜索之后,我在DigitalOcean上看到了这篇精彩的文章.

hasged是一种潜在的解决方案,不会影响安全性.

我只是引用了这篇文章中的相关部分.

基于HAVEGE原理,并且之前基于其相关联的库,hasged允许基于处理器上的代码执行时间的变化来生成随机性.由于一段代码几乎不可能花费相同的执行时间,即使在同一硬件上的相同环境中,运行单个或多个程序的时间也应该适合种子随机源.在反复执行循环后,使用处理器的时间戳计数器(TSC)中的差异,伪造的实现会使系统的随机源(通常为/ dev/random)变为种子

如何安装hasged

请按照本文中的步骤操作.https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

我在这里贴了它

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有