Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working ONLY with /dev/random in Java

I have a HRNG that feeds /dev/random in Debian Wheezy. It's fast, so blocking will not be a problem. Now, in my Java code I want to ensure that I use the entropy in /dev/random and ONLY that entropy. I have no interest in using anything out of /dev/urandom.

I want to force Java's SecureRandom to ONLY get entropy from /dev/random. As I understand the implementation at present, it uses /dev/urandom when getBytes() is called, but /dev/random when generateSeed() is called. I'm at a loss understanding why.

As I understand it, the only reason to read from /dev/urandom is if you favour speed over security. I want the highest quality entropy possible. /dev/urandom will just not do.

So, how do I force SecureRandom to ONLY use /dev/random (supplied by a HRNG) and never touch anything from an inferior PRNG (like /dev/urandom)?

Thanks a mil.

like image 949
user3335193 Avatar asked May 17 '14 16:05

user3335193


People also ask

Does Java use dev random?

By default, the JVM seeds the SecureRandom class using /dev/random , therefore your Java code can block unexpectedly.

Is Dev random truly random?

Strictly speaking, /dev/random is not really completely random. /dev/random feeds on hardware sources which are assumed to be unpredictible in some way; then it mixes such data using functions (hash functions, mostly) which are also assumed to be one-way.

What is Dev random used for?

/dev/random uses an entropy pool of 4096 bits (512 Bytes) to generate random data and stops when the pool is exhausted until it gets (slowly) refilled. /dev/random is designed for generating cryptographic keys (e.g. SSL, SSH, dm-crypt's LUKS), but it is impractical to use for wiping current HDD capacities: what makes ...

What is the difference between Dev random and Dev urandom?

'Urandom' is used where there is constant need of random numbers and its randomness is not much important while 'random' is used where there is a security concern and its randomness should be reliable as it blocks outputting random numbers if entropy is not up to the mark.


1 Answers

This answer assumes you know what you're doing. In other cases, use of /dev/random should be minimized.

/dev/random acts like a normal file, therefore any program which can read any file can read from /dev/random. You probably know that cat /dev/random outputs random data directly from it, and if it does this fast enough, you might in fact want to use it. So, if everything else fails, you'll be always be able to directly read that file...

So, if you look at the source of SecureRandom, you discover that it uses SecureRandomSpi for the actual work. It turns out that NativePRNG.Blocking does what you want:

A NativePRNG-like class that uses /dev/random for both seed and random material. Note that it does not respect the egd properties, since we have no way of knowing what those qualities are. This is very similar to the outer NativePRNG class, minimizing any breakage to the serialization of the existing implementation. Since: 1.8

The problem might be the Since 1.8, which leaves you with the possibility to backport it to earlier platforms, if you can't use Java 8 yet. The sourcecode is available after all.

So, now let's put this in code:

We have to select the specific implementation to use. To find the exact name, we output all available services with the following line:

for (Provider p: Security.getProviders()) p.getServices().forEach(System.out::println);

We then search for Native in there, and we find the folllowing entry:

SUN: SecureRandom.NativePRNGBlocking -> sun.security.provider.NativePRNG$Blocking

This means we can instantiate the SecureRandom object like below to do what you want:

SecureRandom sr = SecureRandom.getInstance("NativePRNGBlocking", "SUN");

A simple test

byte[] b = new byte[10000];
sr.nextBytes(b);
System.out.println(Arrays.toString(b));

takes ages, I had to lower the amount of read bytes. If it works for you, congratulations, you're reading from /dev/random!

Notice though that this class is in the sun.security.provider package, which is not guaranteed to be available everywhere. For example, it will probably not work on Android. If this fine, then this solution will work, otherwise you should just directly read it as a file.

Don't read from /dev/random on Android. Please.

like image 115
tilpner Avatar answered Sep 28 '22 19:09

tilpner