SecureRandom.getInstance ("SHA1PRNG", "SUN") always blocks, and the new SecureRandom () is not?

I would like to consult with some question about the general myth of SecureRandom in Java, about the trade-off between security and performance.

I searched the Internet for a while, and I collected the following information. I would like people to help me confirm what I have, and I hope to get some ideas on what to actually choose for implementation.

Basically, here are some of the most popular and thorough articles for SecureRandom:

Proper use of Java SecureRandom: http://www.cigital.com/justice-league-blog/2009/08/14/proper-use-of-javas-securerandom/

Problems using Java SecureRandom: http://www.cigital.com/justice-league-blog/2014/01/06/issues-when-using-java-securerandom/

Using the SecureRandom class: http://moi.vonos.net/java/securerandom/

And Sun's official "confession" about the bug / confusion and the proposed release in Java 8: http://openjdk.java.net/jeps/123

Now that Java 8 is missing, I honestly don’t know how best it was fixed just by looking at the documentation: http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

So in the end, this is what I got (please help me find out if I am sorted):

People like Amit Networks suggest using specific instances, such as: SecureRandom sr3 = SecureRandom.getInstance ("SHA1PRNG", "SUN"), where in fact Sun tells us that this will always read / dev / random (? ?), which means that it can potentially be blocked for EVERY call. Unlike if you use the new SecureRandom (), it will always read from / dev / urandom if the generateSeed () function is not called. Cm.

http://bugs.java.com/view_bug.do?bug_id=6202721

Does this mean that β€œnew SecureRandom ()” is still preferable in current Java? Not many other documents that I found have articulated the above point explicitly, so I want to know if this is still true?

Now, if "new SecureRandom ()" is the choice and will result in never blocking the call, then I think I should do for periodic re-entry:

Make SecureRandom a static instance in the class and let another Executor thread periodically call generateSeed () on it, so even though the call is blocked, it does not affect my main request processing thread in my application. Does that sound like a good way to do this?

Encourage Java lovers and cryptanalysts to shed light on this issue. Thanks!

Edit: Another useful thread here seems to confirm my assumptions: https://bugs.openjdk.java.net/browse/JDK-4705093

+7
java cryptography
source share
1 answer

EDIT : First of all; if the /dev/random or /dev/urandom blocks make sense, first try and fix this particular problem. The solutions below relate to trying to fix SecureRandom in Java itself, so it is less dependent on these special devices.


Make SecureRandom a static instance in the class and let another Executor thread periodically call generateSeed () on it, so even though the call is blocked, it does not affect my main request processing thread in my application. Does that sound like a good way to do this?

No, you should use nextBytes() in this case, since the internal call to generateSeed() uses the original seed information provider. In other words, you could create a separate instance of SecureRandom . Please note that whenever you have a SecureRandom instance with a fairly high state and a good support algorithm, frequent repetition is often not required (since this is very unlikely to create a loop). If you ever need higher entropy, generate a new random class each time or use random extraction using SecureRandom.getInstanceStrong() .

The default use of new SecureRandom() is probably best. Usually you should always specify the exact name of the algorithm for cryptographic algorithms (for example, "AES/CBC/PKCS5Padding" ), but for protected random functions it is better to let the system know which algorithm is best. If you want to change something, change it in the command line constructs and make sure that /dev/urandom is available on Unix systems.

If you still have problems with blocking, create a central system planted by SecureRandom . Create a new seed material using nextBytes() and put it on the new SecureRandom using the SecureRandom(byte[] seed) constructor SecureRandom(byte[] seed) . This method should only be used if new SecureRandom() cannot handle the situation.

Although the delivery of the initial semester is now explicit using the constructor, the constructor itself does not guarantee that it is used exclusively for seeding RNG. However, most likely this is the case, so it is unlikely to be blocked. SecureRandom is thread safe , so you do not need to synchronize access to it.

Using the new Java 8 SecureRandom.getInstanceStrong() more likely to be blocked. I suppose they added this to make the default instances non-blocking. Generating an RSA key pair usually requires a lot of entropy, so it is likely that returned instances use blocking calls to /dev/random .

In general, using SecureRandom for special occasions is still pretty messy. Fortunately, this is just a problem for a very limited number of use cases.

+4
source share

All Articles