Java SecureRandom的合理使用
来源:互联网 发布:党员教师知敬畏明底线 编辑:程序博客网 时间:2024/04/28 23:03
When generating random numbers in Java for cryptographic purposes, many developers often use thejava.security.SecureRandom
class. And while the java.security.SecureRandom
class is designed to generate cryptographically secure random numbers, there are a few subtleties in the API, and if it is used improperly the output can become predictable. At Cigital we have witnessed a number of cases where this is true. The following is a guide to the proper use of Java’sjava.security.SecureRandom
class.
First, let’s take a quick look at how the java.security.SecureRandom
API works. Thejava.security.SecureRandom
class does not actually implement a pseudorandom number generator (PRNG) itself. It uses PRNG implementations in other classes to generate random numbers. A number of actual PRNGs may actually be used when an instance of java.security.SecureRandom
is created. The PRNGs are part of Java cryptographic service providers (CSPs). In Sun’s Java implementation, the SUN CSP is used by default. On Windows, the SUN CSP uses the SHA1PRNG implemented in sun.security.provider.SecureRandom by default. On Solaris and Linux, the SUN CSP default is to use sun.security.provider.NativePRNG which simply provides the output of the/dev/urandom
PRNG provided by the operating system. If however, on Solaris/Linux, the java.security configuration file in the JRE is modified such that securerandom.source is set to something other than file:/dev/urandom
, then the SHA1PRNG implemented in sun.security.provider.SecureRandom is used, as on Windows. Of course, an application can choose not to use the defaults, and can always specify a particular PRNG implemented by a particular cryptographic provider. In Cigital’s experience, most Java applications that use java.security.SecureRandom
actually use the SHA1PRNG provided by the SUN CSP under the cover.
Now, an application will end up with an instance of SHA1PRNG implemented in sun.security.provider.SecureRandom
using the following calls:
Note that according to Sun’s documentation, the returned java.security.SecureRandom
instance is not seeded by any of these calls. If after one of these calls,java.security.SecureRandom.nextBytes(byte[])
is called, then the PRNG is seeded using a secure mechanism provided by the underlying operating system (starting with JRE 1.4.1 in Windows and JRE 1.4.2 in Linux and Solaris). Ifjava.security.SecureRandom.setSeed(long)
or java.security.SecureRandom.setSeed(byte[])
is called before a call tojava.security.SecureRandom.nextBytes(byte[])
, then the internal seeding mechanism is bypassed, and only the provided seed is used to generate random numbers.
For those who are not familiar with the inner workings of cryptographic PRNGs, their job is to take a relatively small random seed and use it to produce deterministic output that seems random to anybody that does not know what the seed is. The PRNG tries to ensure that the output does not reveal any information about the seed, and that somebody observing the output cannot predict future outputs without knowing the seed.
By bypassing the internal secure seeding mechanism of the SHA1PRNG, you may compromise the security of your PRNG output. If you seed it with anything that an attacker can potentially predict (e.g. the time when the PRNG instance was created), then usingjava.security.SecureRandom
may not provide the level of security that you need.
Finally, regardless of how well the PRNG is seeded, it should not be used indefinitely without reseeding. There are two approaches that can be used for longer-term security of PRNG output:
- Periodically throw away the existing
java.security.SecureRandom
instance and create a new one. This will generate a new instance with a new seed. - Periodically add new random material to the PRNG seed by making a call to
java.security.SecureRandom.setSeed
(java.security.SecureRandom.generateSeed(int)
).
In summary, keep the following in mind when using java.security.SecureRandom
:
- Always specify the exact PRNG and provider that you wish to use. If you just use the default PRNG, you may end up with different PRNGs on different installations of your application that may need to be called differently in order to work properly. Using the following code to get a PRNG instance is appropriate:
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
- When using the SHA1PRNG, always call
java.security.SecureRandom.nextBytes(byte[])
immediately after creating a new instance of the PRNG. This will force the PRNG to seed itself securely. If for testing purposes, you need predictable output, ignoring this rule and seeding the PRNG with hard-coded/predictable values may be appropriate. - Use at least JRE 1.4.1 on Windows and at least JRE 1.4.2 on Solaris and Linux. Earlier versions do not seed the SHA1PRNG securely.
- Periodically reseed your PRNG as observing a large amount of PRNG output generated using one seed may allow the attacker to determine the seed and thus predict all future outputs.
See other posts on SecureRandom
Issues to be aware of when using Java’s SecureRandom
SecureRandom Implementation (sun.security.provider.SecureRandom – SHA1PRNG)
SecureRandom Implementation (sun.security.provider.NativePRNG)
- Java SecureRandom的合理使用
- hashmap的合理使用
- 职权的合理使用
- SecureRandom
- SecureRandom
- 关于JAVA多线程并发synchronized的测试与合理使用
- 关于JAVA多线程并发synchronized的测试与合理使用
- 关于JAVA多线程并发synchronized的测试与合理使用
- Java 8 SecureRandom 生成随机数
- 涂层刀具的合理使用
- DBGridEh 合理的排序使用
- JDBC链接的合理使用
- Model的合理使用时机
- 使用svn的合理姿势
- 合法合理的使用webfont
- 如何合理的使用JSON
- 如何合理使用java接口collection
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
- jQuery(8) 实现Ajax应用
- 7.1.4构造函数
- MySQL学习----MySQL数据类型----01MySQL 数值类型
- 丁海森: 域名投资无须营业执照,小生意,大买卖?
- 输入输出流
- Java SecureRandom的合理使用
- Project : error PRJ0019: 某个工具从以下位置返回了错误代码: "正在执行预链接事件..."
- tomcat内存调试
- Spring定时任务的几种实现
- win32控制台程序中使用CString和string .
- 最短路径算法——Dijkstra,Bellman-Ford,Floyd-Warshall,Johnson
- LaTeX 中的特殊符号
- vs2010 配置lib文件
- hdu4869Turn the pokers 组合数学+求逆元