Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I know from experience that reading from /dev/random blocks when the Linux kernel entropy pool runs out of entropy. Also, I've seen many articles and blog entries stating that when running on Linux, java.security.SecureRandom uses /dev/random as its entropy source and thus blocks when the kernel entropy pool runs out of entropy.

However, I'm unable to produce an experiment which causes SecureRandom to block. Conversely, it seems easy to get a simple bash one-liner which reads from /dev/random to block.

Here's the java code I'm using for these experiments:

import java.security.SecureRandom;

public class A {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom();
        int out = 0;
        for (int i = 0; i < 1<<20 ; i++) {
            out ^= sr.nextInt();
        }
        System.out.println(out);
    }
}

It generates just over 1,000,000 random 32-bit integers. That should be 2^(20 + log2(32)) = 2^25 bits or 2^22 (a little over 4 million) bytes of entropy, right? However, it never blocks. It always finishes in about 1.2 seconds no matter whether I wiggle the mouse or not.

The bash one-liner I used is:

head -c 100 /dev/random | xxd

This blocks easily. As long as I keep my hand off of the mouse and keyboard, it'll sit there doing nothing for several minutes. And I'm only asking for 100 bytes of entropy.

Surely I'm missing something here. Could someone explain what's going on?

Thanks!

share|improve this question
    
There is no reason for a CSPRNG to block again after it's seeded once. Blocking is useful after reboot, hibernation etc. because you need sufficient initial entropy, but "entropy drain" is not a threat in practice. –  CodesInChaos Aug 14 '13 at 19:35
add comment

2 Answers

up vote 17 down vote accepted

Both OpenJDK and Sun read from /dev/urandom, not /dev/random, at least on the machine where I tested (OpenJDK JRE 6b27 and Sun JRE 6.26 on Debian squeeze amd64). For some reason, they both open /dev/random as well but never read from it. So the blog articles you read either were mistaken or applied to a different version from mine (and, apparently, yours).

You can check whether yours reads from /dev/random or /dev/urandom by tracing it:

strace -o a.strace -f -e file java A

and look for the relevant part of the trace:

21165 open("/dev/random", O_RDONLY)     = 6
…
21165 open("/dev/urandom", O_RDONLY)    = 7
…
21165 read(7, "\322\223\211\262Zs\300\345\3264l\254\354[\6wS\326q@", 20) = 20
…

Don't worry, /dev/urandom is perfectly fine for cryptography.

share|improve this answer
    
Simple, answers my question, backs up his claims. Thanks and +1. (That is +1 if I had enough reputation to upvote...) –  user1483512 Aug 15 '13 at 13:09
    
Apparently on Android, SecureRandom has a different implementation which has caused repeated values: theregister.co.uk/2013/08/12/… –  Will Sargent Apr 13 at 20:07
add comment

$JAVA_HOME/lib/security/java.security: securerandom.source property dictates which device to use when using SecureRandom. The default value is /dev/urandom, which means Java will never block.

For new comers to the topic, /dev/urandom is special version of /dev/random, which will use true entropy from /dev/random when available and then pseudo random data seeded true entropy if it was available.

In headless, VM and Cloud environments, I recommend seeding urandom from an external source, such as http://random.org

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.