Standard JDK implementations of java.util.Random use a Linear Congruential Generator (LCG) algorithm for providing random numbers.
The problem with this algorithm is that it’s not cryptographically strong.
In other words, the generated values are **much more predictable**,
therefore attackers could use it to compromise our system.
To overcome this issue, we should use java.security.SecureRandom in any security decisions.
It produces cryptographically strong random values by using a cryptographically strong pseudo-random number generator (CSPRNG).
For a better understanding of the difference between LCG and CSPRNG,
let us look at the below chart presenting a distribution of values for both algorithms:
Reference:
