JVM的随机数与熵池策略
在apache-tomcat官方文档:如何让tomcat启动更快里面提到了一些启东市的优化项,其中一项是关于随机数生成时,采用的“熵源”(entropy source)的策略。
该文档提到tomcat7的session id 的生成主要是通过java.security.SecureRandom生成随机数来实现,随机数算法使用的是"SHA1PRNG",声明如下:
private String secureRandomAlgorithm = "SHA1PRNG";
在sun/oracle的jdk中,这个算法的提供者在底层依赖到操作系统提供的随机数数据,在linux上,与之相关的是/dev/random和/dev/urandom,对于这两个设备块的描述以前也见过讨论随机数的文章。,在wiki中有比较详细的描述,摘抄过来,先看/dev/random:
而/dev/urandom则是一个非阻塞的发生器:
另外wiki里也提到了为什么linux内核里的随机数生成器采用SHA1散列算法而非加密算法,是为了避开法律风险(密码出口限制)。
回到tomcat文档里的建议,采用非阻塞的熵源(entropy source),通过java系统属性来设置:
-Djava.security.egd=file:/dev/./urandom
这个系统属性egd表示熵收集守护进程(entropy source daemon),但这里值为何要在dev和random之间加一个点呢?这里是jdk中的一个bug,在这个bug的连接里有人反馈及时对securerandom.source设置为/dev/urandom它也仍然使用的/dev/random,有人提供了变通的解决方法,其中一个变通的做法是对securerandom.source,设置为/dev/./urandom才行。
java.security文件里,配置里仍使用的是/dev/urandom:
#
# Select the source of seed data for SecureRandom. By default an
# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
# accessing the URL then the traditional system/thread activity
# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
# This "NativePRNG" reads random bytes directly from /dev/urandom.
#
# On Windows systems, the URLs file:/dev/random and file:/dev/urandom
# enables use of the Microsoft CryptoAPI seed functionality.
#
securerandom.source=file:/dev/urandom