If you want a cryptographically strong random numbers in Java, you use SecureRandom
. Unfortunately, SecureRandom
can be very slow. If it uses
Use the secure random as initialization source for a recurrent algorithm; you could use then a Mersenne twister for the bulk work instead of the one in UncommonMath, which has been around for a while and proven better than other prng
http://en.wikipedia.org/wiki/Mersenne_twister
Make sure to refresh now and then the secure random used for the initialization, for example you could have one secure random generated per client, using one mersenne twister pseudo random generator per client, obtaining a high enough degree of randomization
If you want true random data, then unfortunately you have to wait for it. This includes the seed for a SecureRandom
PRNG. Uncommon Maths can't gather true random data any faster than SecureRandom
, although it can connect to the internet to download seed data from a particular website. My guess is that this is unlikely to be faster than /dev/random
where that's available.
If you want a PRNG, do something like this:
SecureRandom.getInstance("SHA1PRNG");
What strings are supported depends on the SecureRandom
SPI provider, but you can enumerate them using Security.getProviders()
and Provider.getService()
.
Sun is fond of SHA1PRNG, so it's widely available. It isn't especially fast as PRNGs go, but PRNGs will just be crunching numbers, not blocking for physical measurement of entropy.
The exception is that if you don't call setSeed()
before getting data, then the PRNG will seed itself once the first time you call next()
or nextBytes()
. It will usually do this using a fairly small amount of true random data from the system. This call may block, but will make your source of random numbers far more secure than any variant of "hash the current time together with the PID, add 27, and hope for the best". If all you need is random numbers for a game, though, or if you want the stream to be repeatable in future using the same seed for testing purposes, an insecure seed is still useful.
If your hardware supports it try using Java RdRand Utility of which I'm the author.
Its based on Intel's RDRAND
instruction and is about 10 times faster than SecureRandom
and no bandwidth issues for large volume implementation.
Note that this implementation only works on those CPU's that provide the instruction (i.e. when the rdrand
processor flag is set). You need to explicitly instantiate it through the RdRandRandom()
constructor; no specific Provider
has been implemented.
It sounds like you should be clearer about your RNG requirements. The strongest cryptographic RNG requirement (as I understand it) would be that even if you know the algorithm used to generate them, and you know all previously generated random numbers, you could not get any useful information about any of the random numbers generated in the future, without spending an impractical amount of computing power.
If you don't need this full guarantee of randomness then there are probably appropriate performance tradeoffs. I would tend to agree with Dan Dyer's response about AESCounterRNG from Uncommons-Maths, or Fortuna (one of its authors is Bruce Schneier, an expert in cryptography). I've never used either but the ideas appear reputable at first glance.
I would think that if you could generate an initial random seed periodically (e.g. once per day or hour or whatever), you could use a fast stream cipher to generate random numbers from successive chunks of the stream (if the stream cipher uses XOR then just pass in a stream of nulls or grab the XOR bits directly). ECRYPT's eStream project has lots of good information including performance benchmarks. This wouldn't maintain entropy between the points in time that you replenish it, so if someone knew one of the random numbers and the algorithm you used, technically it might be possible, with a lot of computing power, to break the stream cipher and guess its internal state to be able to predict future random numbers. But you'd have to decide whether that risk and its consequences are sufficient to justify the cost of maintaining entropy.
Edit: here's some cryptographic course notes on RNG I found on the 'net that look very relevant to this topic.
I faced same issue. After some Googling with the right search terms, I came across this nice article on DigitalOcean.
I am merely quoting the relevant part from the article here.
Based on the HAVEGE principle, and previously based on its associated library, haveged allows generating randomness based on variations in code execution time on a processor. Since it's nearly impossible for one piece of code to take the same exact time to execute, even in the same environment on the same hardware, the timing of running a single or multiple programs should be suitable to seed a random source. The haveged implementation seeds your system's random source (usually /dev/random) using differences in your processor's time stamp counter (TSC) after executing a loop repeatedly
Follow the steps in this article. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged
I have posted it here
My experience has been only with slow initialization of the PRNG, not with generation of random data after that. Try a more eager initialization strategy. Since they're expensive to create, treat it like a singleton and reuse the same instance. If there's too much thread contention for one instance, pool them or make them thread-local.
Don't compromise on random number generation. A weakness there compromises all of your security.
I don't see a lot of COTS atomic-decay–based generators, but there are several plans out there for them, if you really need a lot of random data. One site that always has interesting things to look at, including HotBits, is John Walker's Fourmilab.