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.
Random and Secure Random
Random r1 = new Random(165);
Random r2 = new Random(165);
int n ,n2;
for (int i = 0; i < 5; i++) {
n = r1.nextInt();
n2 = r2.nextInt();
System.out.println(n + " " + n2);
}Output ->
-1120472427 -1120472427
1501130588 1501130588
-807469490 -807469490
-1259549308 -1259549308
-1115179331 -1115179331
as you can see Pseudo-random gives us the same values
Now let’s try the same work with SecureRandom
byte[] s = new byte[] { (byte) 0xA5 };
SecureRandom sr1 = new SecureRandom(s);
SecureRandom sr2 = new SecureRandom(s);
if(sr1.nextInt() == sr2.nextInt()) {
System.out.println("Same seed");
} else {
System.out.println("Different seed");
}Output -> Different seed