javarhelrhel7secure-random

RHE 7 Not respecting java Secure Random Seed


I have a quandary on my hands. I created an AES service to encrypt/decrypt sensitive information. The AES key is randomly generated using java's SecureRandom. I have a protected file that stores the seed and upon calling the service the seed is populated into the Secure Random class.

To make sure it works I have the following logic:

private boolean secureRandom(final String seed) {
  SecureRandom sr1 = new SecureRandom(seed.getBytes(UTF8_CHARSET));
  SecureRandom sr2 = new SecureRandom(seed.getBytes(UTF8_CHARSET));
  //Two secure random with the same seed should generate the same results
  boolean secureRandomWorks = sr1.nextLong() == sr2.nextLong();
  if (!secureRandomWorks) {
    System.err.println("Secure random not supported. Defaulting to old key");
  }
  return secureRandomWorks;
}

The idea here is I should be able to create two secure random objects with the same seed and they should both return the same value upon the call to nextLong()

When I deploy my application on a windows machine this works fine, but when I deploy it on a RHEL 7 machine I get my error.

I was under the impression that as long as the seed is the same, both instances will always produce the same output. This seems to be the case on windows, but not when I tested it on RHEL 7 this doesn't seem to be the case.

I created this simple test to see verify:

SecureRandom sr1 = new SecureRandom("encryptionKey".getBytes("UTF-8"));
SecureRandom sr2 = new SecureRandom("encryptionKey".getBytes("UTF-8"));

for (int i = 0; i < 1000; i++) {
  System.out.println(sr1.nextLong() == sr2.nextLong());
}

And on windows every output was true while on RHEL 7 this was false.

Any idea's suggestions on what might be causing RHEL 7 to ignore the seed?


Solution

  • Turns out that RHEL 7 (and Linux machines in general) uses a different algorithm by default than windows. Linux uses NativePRNG while Windows uses SHA1PRNG.

    Linux utilizes the built in /dev/random or /dev/urandom with the use of NativePRNG.

    With this in mind I was able to change how I initialize the SecureRandom object

    private static final String ALGORITHM = "SHA1PRNG";
    private static final String PROVIDER = "SUN";
    
    private SecureRandom getSecureRandom(String seed) throws NoSuchAlgorithmException, NoSuchProviderException {
      SecureRandom sr = SecureRandom.getInstance(ALGORITHM, PROVIDER);
      sr.setSeed(seed.getBytes(UTF8_CHARSET));
      return sr;
    }
    

    From the documentation getInstance does not seed the object thus it does as I need.

    The returned SecureRandom object has not been seeded. To seed the returned object, call the setSeed method. If setSeed is not called, the first call to nextBytes will force the SecureRandom object to seed itself. This self-seeding will not occur if setSeed was previously called.

    Now it is forced to use what I need and I shouldn't have an issue with RHEL 7.