Hacker News new | past | comments | ask | show | jobs | submit login

This is a pretty great post. We need lots more posts on practical exploit development for RNG flaws, because there are a lot of bad random number generators out there.

I want to respond to this headline, though. Use of MT as a CSPRNG is very, very common in PHP applications. And it's also true that MT is the algorithm used by Ruby for it's "rand". But this is not a very common Ruby flaw, at least not like it is in PHP, because virtually every Ruby build provides an explicit secure random number generator, either through OpenSSL or (more commonly) through Rails' SecureRandom.

You should know that unless your RNG calls itself "secure" or "cryptographic" --- like, in the function name --- you are using rand(), not a CSPRNG, and you can't count on it for security ever. You will have the exact same problem in most mainstream languages. Secure random number generators say they're secure. Nobody says Ruby's rand() is secure.

(I'm pretty sure the same is true of Python, but I'm less confident of the specifics. I think this is a very fair issue to raise with PHP in general, though.)




> (I'm pretty sure the same is true of Python, but I'm less confident of the specifics. I think this is a very fair issue to raise with PHP in general, though.)

Yeah, Python's random module uses MT, but you can use PyCrypto, which provides an API-compatible cryptographically secure module (PyCrypto.Random.random).


The Python docs[0] for the random module also state, quite clearly, that "the basic function random()... is completely unsuitable for cryptographic purposes".

[0] http://docs.python.org/3.3/library/random.html


Very very minor nitpick/addendum to your point. Some languages let you swap out the rand function for a secure implementation. In those cases its important to make sure that that mechanism is actually in place.

In Perl for example:

http://search.cpan.org/~mkanat/Math-Random-Secure-0.06/lib/M...


Which is evil, because you want assessors and code reviewers to be able to quickly spot which RNG you're using.


Not to mention wanting something to break if the secure implementation somehow were separated from the code using it (versus silently reverting to PRNG).


Is there any advice you're able to give on how to distinguish situations where you need secure RNG from those that don't matter?

For instance, you definitely need it in poker hand generation - would you need it for random loot generation in an MMO?

Also by "secure" you mean /dev/random, and /dev/urandom is used as if it was rand()?


Using a secure RNG is always a good idea, unless you know you need lots of (predictable given the seed) random numbers for example in Monte Carlo sampling.

Even in randomized algorithms you may have to be careful what RNG you use, because of DDOS risk. For example see the problems with Python and Ruby hash tables that could be exploited to have worst-case behavior because their behavior was entirely predictable.

In a MMO you most certainly want to use a secure RNG, as cheating is rife in them. If a player can get an advantage by predicting the RNG, someone will.


You should pretty much just default to secure random.

/dev/urandom is fine; in Ruby apps, I'd use OpenSSL::Random.random_bytes or ActiveSupport::SecureRandom.random_number.


If OpenSSL::Random isn't working (because OpenSSL is not installed for example) there is also SecureRandom in the stdlib. It tries to do the right thing in any situation: Use OpenSSL:Random if available, otherwise it will fall back to what's available in the OS you're on.


What cases do you reserve /dev/random for? SSH keygen?

Do those functions just read from /dev/urandom?


I don't. Just use urandom.


In Python os.urandom provides random string suitable for cryptographic use.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: