Difference between java.util.Random and java.security.SecureRandom
The java.security.SecureRandom is a more secure version of java.util.Random, which provides a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) in Java.
java.security.SecureRandom is always preferred over java.util.Random for generating sensitive random numbers, such as generating an encryption key in a cryptographic application or session ID on a web server or in password generators to create highly secure passwords.
Here are a few reasons why java.security.SecureRandom should be used in sensitive applications:
1. java.util.Random implementations use a Linear Congruential Generator (LCG) to produce pseudorandom values, which are highly predictable.
On the other hand, most java.security.SecureRandom implementations use a pseudorandom number generator (PRNG), which uses a deterministic algorithm to produce a pseudorandom sequence from a truly random seed.
2. java.util.Random uses the system time for the seed. java.security.SecureRandom takes random data from an underlying operating system. In Linux/Solaris, the random numbers are created from the entropy pool by reading from /dev/random and /dev/urandom files.
3. If two instances of java.util.Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers. This is not the case with java.security.SecureRandom, which seeds itself from sources of entropy obtained from the operating system, such as timings of I/O events, which are practically undetectable.
4. The java.util.Random class uses a 48-bit seed, whereas java.security.SecureRandom usually uses a 128-bit or 160-bit seed. Therefore, only 248 attempts are required to break the Random class, which might not even take a second on modern computers. On the other hand, 2128 or 2160 attempts will be required for SecureRandom, which would take years to break even with today’s CPUs computational power.
5. java.security.SecureRandom produces non-deterministic output as it doesn’t depend upon the system clock for a seed value. So it is impossible to predict previous and future random numbers. java.util.Random, on the other hand, uses the system clock as the seed and can be easily reproduced if the time at which the seed was generated is known.
6. LCGs are very fast and typically require only 32- or 64-bits to retain state. On the other hand, creating a java.security.SecureRandom instance is quite expensive than creating a java.util.Random instance and is about 30-50 times slower than Random.
Also, the generateSeed() and nextBytes() methods of SecureRandom may get blocked on Linux if not enough entropy is available and as entropy is being gathered in /dev/random file. Here’s what Wikipedia has to say:
The generator keeps an estimate of the total number of bits of noise in the entropy pool. From this entropy pool, random numbers are created. When read, the /dev/random device will only return random bytes within the estimated number of bits of noise in the entropy pool. /dev/random should be suitable for uses that need very high-quality randomness, such as a one-time pad or key generation. When the entropy pool is empty, reads from /dev/random will block until additional environmental noise is gathered.
7. It is worth noting that java.security.SecureRandom is a subclass of java.util.Random and inherits all nextX() methods from it, where X can be Boolean, Double, Float, Gaussian, Int, and Long.
8. Initialization of java.util.Random and java.security.SecureRandom:
Random can be initialized as :
|
1 |
Random rand = new Random(System.nanoTime()); |
SecureRandom can be initialized as:
|
1 |
SecureRandom rand = new SecureRandom(SecureRandom.getSeed(20)); |
Here, the number 20 denotes 160-bit seed as 20 bytes = 160 bits.
9. Javadoc itself suggests to use java.security.SecureRandom to get a cryptographically secure pseudorandom number generator in security-sensitive applications.
That’s all about the differences between java.util.Random and java.security.SecureRandom.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)