java中的SecureRandom在linux中的实现
来源:互联网 发布:网络刷信誉兼职可信吗 编辑:程序博客网 时间:2024/05/22 10:45
在安全系统中,通常我们会使用securerandom去更安全的生成随机数,而默认的SecureRandom里使用的算法是SHA1PRNG。
Linux中的随机数发生器
在Linux操作系统中,有一个特殊的设备文件,可以用作随机数发生器或伪随机数发生器。
/dev/random
在读取时,/dev/random设备会返回小于熵池噪声总数的随机字节。/dev/random可生成高随机性的公钥或一次性密码本。若熵池空了,对/dev/random的读操作将会被阻塞,直到从别的设备中收集到了足够的环境噪声为止。
当然你也可以设置成不堵塞,当你在open 的时候设置参数O_NONBLOCK, 但是当你read的时候,如果熵池空了,会返回-1
/dev/urandom
/dev/random的一个副本是/dev/urandom ("unlocked",非阻塞的随机数发生器[4]),它会重复使用熵池中的数据以产生伪随机数据。这表示对/dev/urandom的读取操作不会产生阻塞,但其输出的熵可能小于/dev/random的。它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码。
Linux下设置随机数
/proc/sys/kernel/random
在此目录下,可以配置/dev/random的参数
Poolsize
The file poolsize gives the size of the entropy pool
Read-wakeup_threadhold
The file read_wakeup_threshold contains the number of bits ofentropy required for waking up processes that sleep waiting for entropy from /dev/random. The default is 64.
write_wakeup_threshold
The filewrite_wakeup_threshold contains the number of bits of entropy below which wewake up processes that do a select(2) or poll(2) for write access to /dev/random.
在JAVA中的配置发生器
在JAVA中可以通过两种方式去设置指定的随机数发生器
1. -Djava.security.egd=file:/dev/random或者 -Djava.security.egd=file:/dev/urandom
2. 修改配置文件java.security 在jvm_home\jre\lib\security
参数securerandom.source=file:/dev/urandom
/dev/random 是堵塞的,在读取随机数的时候,当熵池值为空的时候会堵塞影响性能,尤其是系统大并发的生成随机数的时候,如果在随机数要求不高的情况下,可以去读取/dev/urandom
整个流程如下:
JAVA中首先读取系统参数java.security.egd,如果值为空的时候,读取java.security配置文件中的参数securerandom.source, 在通常情况下,就是读取参数securerandom.source,默认值是/dev/urandom,也就是因该是不堵塞的。
但实际情况是,在测试linux环境下的时候,你会发现默认值却是堵塞的。
查看代码sun.security.provider.SeedGenerator.java
if (egdSource.equals(URL_DEV_RANDOM) || egdSource.equals(URL_DEV_URANDOM)){ try { instance = new NativeSeedGenerator(); if (debug != null) { debug.println("the instance:"+instance.getClass()); debug.println("Using operating system seed generator"); } } catch (IOException e) { if (debug != null) { debug.println("Failed to use operating system seed " + "generator: "+ e.toString()); } } } else if (egdSource.length() != 0) { try { instance = new URLSeedGenerator(egdSource); if (debug != null) { debug.println("Using URL seed generator reading from " + egdSource); } } catch (IOException e) { if (debug != null) debug.println("Failed to create seed generator with " + egdSource + ": " + e.toString()); } }
在代码中可以看到当配置值是file:/dev/random或者file:/dev/urandom的时候,启用NativeSeedGenerator, 而在linux下的NativeSeedGenerator类
class NativeSeedGenerator extends SeedGenerator.URLSeedGenerator{ NativeSeedGenerator() throws IOException { super(); }}
只是简单的继承了一下URLSeedGenerator, 而对URLSeedGenerator默认的构造函数里则强制读取了文件/dev/random
URLSeedGenerator()throwsIOException { this(SeedGenerator.URL_DEV_RANDOM); }
也就是说哪怕设置了-Djava.security.egd=file:/dev/urandom,最后的结果一样是读取file:/dev/random, 不清楚究竟是代码的bug,还是有意为之?但解决办法相当的有趣,因为在上面的代码中强匹配了file:/dev/random,file:/dev/urandom的值
而对linux来说要表示urandom的路径就很多种方式了
比如file:/dev/./urandom 或者 file:/dev/../dev/urandom 这样就可以绕过JAVA的简单检查了,这应该是JAVA的一个security的bug
设置
-Djava.security.egd=file:/dev/./urandom
就可以绕过保护,而使用URLSeedGenerator,读取文件/dev/./urandom 也就是/dev/urandom文件
Tip: 打开security的debug log
通过设置参数
-Djava.security.debug=all
可以控制台看到所有security的log
- java中的SecureRandom在linux中的实现
- java中的SecureRandom在linux中的实现
- java中的SecureRandom在linux中的实现
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom .
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
- [转]Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
- VLAN在linux中的实现
- 线程在Linux中的实现
- 信号量在Linux中的实现
- 加密算法在JAVA中的实现
- 栈在java中的实现
- MD5在Java中的实现
- MangoDB在java中的实现
- SYN Cookie在Linux内核中的实现
- netfilter:Linux 防火墙在内核中的实现
- netfilter:Linux 防火墙在内核中的实现
- iOS开发ASIHTTPRequest中Cookie的使用【6】
- Android应用程序从源码到安装包
- ITL(Interested Transaction List)理解
- BZOJ 3856 Monster C++语言入门题
- 为项目增加自己设计的404、500错误页面
- java中的SecureRandom在linux中的实现
- Intent数据传递
- 网络概论
- android调用camera实现自定义照相
- 把mysql数据表中的字段的默认值设置为空字符串怎么设置
- 关于Rayeager PX2的一些实现
- JSP、Struts2下载中文文件名乱码问题
- Spark 运行架构和解析《二》
- 字节序转换函数