The JDK includes a class,
implements a PRNG. Although it’s fine for light-duty use, it
has the following shortcomings:
It uses an algorithm that produces a predictable sequence of numbers.
If you don’t give
Randoma seed value, it uses the value of the system clock. This is a predictable seed. Let’s say that you create a random number in order to create a cryptographic key. If an attacker knows when you created the random number, even approximately, he or she can guess at likely values of the random number seed. With a relatively small amount of guessing, the attacker can guess which random number seed you’ve used. From this, the attacker can generate the same supposedly random cryptographic key that you just generated. Now the attacker can impersonate you or read your secret messages.
A stronger PRNG,
introduced in JDK 1.1. This class is based around a message digest.
uses the SHA-1 (Secure Hash Algorithm)
message digest algorithm, which produces a 20-byte digest.
Here’s how it works:
SecureRandomneeds to create more pseudo-random numbers, the message digest is updated with the internal state and the counter, which is incremented. This data is digested and returned as the new pseudo-random data.
Because of the irreversible nature of the message digest, it’s very hard to predict the past and future values of the PRNG even if you know its present output.
In practice, you don’t have to worry about the details. Just
SecureRandom instance and call its
nextBytes() method to get pseudo-random data. In
the example that follows, a
SecureRandom is used
to generate 100 bytes of pseudo-random data:
SecureRandom sr = new SecureRandom(); byte pseudoRandom = new byte; sr.nextBytes(pseudoRandom);
SecureRandom provides two constructors:
- public SecureRandom()
This constructor creates a new
SecureRandomand initializes it with automatically generated seed data. This process is called self-seeding and is discussed in the next section.
- public SecureRandom(byte seed)
This constructor takes the given seed data and uses it to initialize a new
- public synchronized void setSeed(byte seed)
This method updates the internal state of the
SecureRandomwith a new set of random seed data. The new data does not replace the original seed, but supplements it.
- public synchronized void nextBytes(byte bytes)
This method fills the given byte array with pseudo-random data.