This system doesn't provide enough entropy to quickly generate high-quality random numbers. The service will not start until enough entropy has been collected.
当在linux系统启动一些应用的时候,有时候会提示这个错误,比如在启动tomcat的时候.更接近一点,涉及到随机数生成的功能,有可能会出现这个问题.
这个问题就是说linux系统的熵值不够了,无法足够生成随机数.
先说比较优美的解决方案:
apt install haveged -y
systemctl start haveged
systemctl enable haveged
安装haveged作为守护进程,并且开机启动.
还有其他解决方法
apt install rng-tools -y
rngd -r /dev/urandom
rngd -r /dev/urandom
这个用法是错的没边,相当于把/dev/urandom
重新导入/dev/random
,欺骗内核让他认为有足够的熵源。如果你用现代内核的话,这个错误不必在意。唯一需要做的就是多等会。
以下转载自SecureRandom的正确使用
什么是安全的随机数?
在安全应用场景,随机数应该使用安全的随机数。密码学意义上的安全随机数,要求必须保证其不可预测性。
怎么得到安全的随机数
可以直接使用真随机数产生器产生的随机数。或者使用真随机数产生器产生的随机数做种子,输入密码学安全的伪随机数产生器产生密码学安全随机数。
非物理真随机数产生器有:
- Linux操作系统的
/dev/random
设备接口 - Windows操作系统的
CryptGenRandom
接口
密码学安全的伪随机数产生器,包括JDK的java.security.SecureRandom
等。
SecureRandom最佳实践
基本用法
java.security.SecureRandom
基本用法:
byte[] values = new byte[128];
SecureRandom random = new SecureRandom();
random.nextBytes(values);
关于种子的设置
要保证得到安全的随机数,需要使用真随机数产生器产生的随机数做种子。
可能的不当用法:
byte[] salt = new byte[128];
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(System.currentTimeMillis()); //使用系统时间作为种子
secureRandom.nextBytes(salt);
此处指定了当前系统时间作为种子,替代系统默认随机源。如果同一毫秒连续调用,则得到的随机数则是相同的。
小结:不要自己指定种子。应当使用系统随机源。
系统默认的随机源是什么?
这取决于$JAVA_HOME/jre/lib/security/java.security
(9之后是$JAVA_HOME/conf/security/java.security
)配置中的securerandom.source
属性。例如jdk1.8中该配置为:
securerandom.source=file:/dev/random
使用无参构造函数实例化SecureRandom
,在大多数系统中,默认的算法是“nativePRNG”,从/dev/random
获取随机数。
熵源不足时阻塞问题
概念回顾:
- “熵值”:即是随机值的不确定性度量值。
- “熵源”:即是随机数的来源。
- “熵输入”:是伪随机数产生器描述从熵源获取的bit串,用来产生种子。
- “种子”:即是输入到伪随机数产生器用于初始化的bit串。
问题描述
在Linux系统中,/dev/random
是系统提供的安全随机数接口。当通过/dev/random
读取随机数的速度可以为产品所接受时,可以直接使用/dev/random
读取的随机数。
有时无法满足产品对随机数的使用要求,熵源不足时存在阻塞,会导致得到随机数的速度太慢。
在读取时,/dev/random
设备会返回小于熵池噪声总数的随机字节。/dev/random
可生成高随机性的公钥或一次性密码本。若熵池空了,对/dev/random
的读操作将会被阻塞,直到收集到了足够的环境噪声为止。
解决方法 提高系统随机数产生器产生随机数速度的一种方法:
采用haveged
守护进程增加系统熵池熵值以提高/dev/random
读取随机数的速度。
小结
SecureRandom
的使用可以采用无参构造方法实例化,无需手动设置种子。
如果出现了熵源不足获取随机数阻塞的问题,再进一步优化即可。
不是安全场景的随机数,使用Random就好。