Live data from Hacker News

How to safely generate a random number

sockpuppet.org

31–40 of 62 posts

Re: How to safely generate a random number

#31
post #23

Earlier quoted context omitted.

If you want a cross-platform secure random source, you can't rely on /dev/urandom existing, so I'm not sure what alternative you're suggesting here.

You can't on the one hand say that OpenJDK Unix SecureRandom uses urandom so it's OK while on the other hand saying that SecureRandom is preferable because it works on platforms without urandom. That's the problem with SecureRandom: it's hard to know exactly what it's doing, as the Android team discovered last year. (On Windows, I'd use CryptGenRandom, although it inspires even less confidence than Linux /dev/random)…

I don't see any contradiction. SecureRandom uses urandom where it's available, and the next best alternative where it's not. Again, I'd like to know what your suggested solution is. The way I see it, you can either:

1) Don't write cross-platform code

2) Use the language implementation

3) Write your own cross-platform code

Assuming (1) isn't an option, it comes down to using SecureRandom or writing your own version of SecureRandom, which strikes me as plain crazy.

Re: How to safely generate a random number

#32
post #23

Earlier quoted context omitted.

You can't on the one hand say that OpenJDK Unix SecureRandom uses urandom so it's OK while on the other hand saying that SecureRandom is preferable because it works on platforms without urandom. That's the problem with SecureRandom: it's hard to know exactly what it's doing, as the Android team discovered last year. (On Windows, I'd use CryptGenRandom, although it inspires even less confidence than Linux /dev/random)…

I don't see any contradiction. SecureRandom uses urandom where it's available, and the next best alternative where it's not. Again, I'd like to know what your suggested solution is. The way I see it, you can either: 1) Don't write cross-platform code 2) Use the language implementation 3) Write your own cross-platform code Assuming (1) isn't an option, it comes down to using SecureRandom or writing your own version of…

If SecureRandom was simply "pull bytes from urandom" on Linux and "pull bytes from CryptGenRandom" on Windows, I wouldn't care enough to argue. But it's not. It's not even "pull bytes from urandom" on Linux; depending on the specific details of your platform, it can be dramatically different than that.

I'm absolutely not recommending that people write their own version of SecureRandom; I'm advising the opposite. Avoid userspace CSPRNGs. Use the system CSPRNG.

Re: How to safely generate a random number

#34
post #26

Earlier quoted context omitted.

If you're ever in Redmond, stop by and we'll go inspire some confidence with the folks maintaining it.

Two immediate questions: forward secrecy and CryptGenRandom's state relative to other WinAPI processes. As in, I'm very clear how the Unix security model protects /dev/random, and less clear about Windows. Some of my C.G.R. thoughts are probably dated. But it's the system CSPRNG, and I think, just use the system CSPRNG.

You have my email right? If you'd like to send me some specific questions and concerns I can try to put them to people who know.

Re: How to safely generate a random number

#35
Why is urandom meant to be more secure?

I read this: "So I'm the maintainer for Linux's /dev/random driver. "... "The main thing which I am much more worried about is that on various embedded systems, which do not have a fine-grained clock, and which is reading from flash which has a much more deterministic timing for their operations, is that when userspace tries to generate long-term public keys immediately after the machine is taken out of the box and plugged in, that there isn't a sufficient amount of entropy, and since most userspace applications use /dev/urandom since they don't want to block, that they end up with keys that aren't very random." - https://www.schneier.com/blog/archives/2013/10/insecurities_...

Is that out of date?

Why so insistent? Why not provide reasons that people can openly verify?

Re: How to safely generate a random number

#36
post #21

Earlier quoted context omitted.

So code that I write that generates keys using OpenSSL isn't indirectly depending on OpenSSL's CSPRNG? Sorry for all the questions. I just want to make sure I'm doing it right and I suspect I'm not the only one that is confused by the article's assertions.

The article (I'm its author) is about programming; it doesn't have strong opinions about how you e.g. configure nginx. As for keys: it depends on the kinds of keys you're generating. If you're building on OpenSSL's primitives --- which, don't --- it'll be hard to get an RSA key without invoking the OpenSSL CSPRNG. But it's not at all hard to avoid OpenSSL's CSPRNG for AES.

Thanks for clarifying.

My project depends on bitcoin-ruby, which uses OpenSSL's EC_KEY_generate_key to generate keys. EC_KEY_generate_key, as far as I can tell, uses OpenSSLs internal PRNG. If I understand you correctly, this is unsafe and it would be better to derive a key from urandom.

Re: How to safely generate a random number

#37

Use urandom, but that's not the end of it. It may be that urandom supports non-blocking reads. Most implementations only check if read() returns -1 then abort, without checking for EAGAIN, not to mention EINTR, or some other subtleties like making sure not to request more than SSIZE_MAX bytes. The randombytes function in NaCl does it right, unfortunately libsodium did their own thing. If you use Python, read from os.…

You can also use random.SystemRandom, which gives you the same interface as random.Random (and the random module) but as a wrapper around os.urandom.

Re: How to safely generate a random number

#38

Why is urandom meant to be more secure? I read this: "So I'm the maintainer for Linux's /dev/random driver. "... "The main thing which I am much more worried about is that on various embedded systems, which do not have a fine-grained clock, and which is reading from flash which has a much more deterministic timing for their operations, is that when userspace tries to generate long-term public keys immediately after t…

urandom and /dev/random aren't two different CSPRNGs. They aren't really even two different designs. They are two different pools into which the same kinds of raw entropy are mixed; the interface to /dev/random's pool happens to have a weird gate on it that tries to determine how much "entropy" is "left" in the pool. I'm oversimplifying a little, but that's the gist of it.

So the problem here is, if you're on a solid state embedded system that doesn't generate enough entropy to drive urandom, you're not doing enough to drive /dev/random either --- except, owing to a design flaw in Linux, on first-boot-ever, where /dev/random's entropy estimator gate saves from you from the bug that is Linux's willingness to give you output from an unseeded RNG. It shouldn't do that. FreeBSD doesn't. But if you're worried about that problem, the correct fix is to explicitly seed urandom from /dev/random on boot, not to use /dev/random in your code!

Once the CSPRNG is seeded, the idea of a "sufficient amount of entropy" is silly. Think of a CSPRNG as a stream cipher. Think of its output as you would the keystream of that cipher. What does it mean, within reason (ie, not hundreds of terabytes) for a keystream to have "sufficient" key in it? Because that's essentially the same question the maintainer for /dev/random is asking.

Re: How to safely generate a random number

#39
post #21

Earlier quoted context omitted.

The article (I'm its author) is about programming; it doesn't have strong opinions about how you e.g. configure nginx. As for keys: it depends on the kinds of keys you're generating. If you're building on OpenSSL's primitives --- which, don't --- it'll be hard to get an RSA key without invoking the OpenSSL CSPRNG. But it's not at all hard to avoid OpenSSL's CSPRNG for AES.

Thanks for clarifying. My project depends on bitcoin-ruby, which uses OpenSSL's EC_KEY_generate_key to generate keys. EC_KEY_generate_key, as far as I can tell, uses OpenSSLs internal PRNG. If I understand you correctly, this is unsafe and it would be better to derive a key from urandom.

Reliance on OpenSSL's CSPRNG isn't a hair-on-fire problem; if it was, your hair would literally be on fire right now, because lots of things do. I just don't think it's a great idea for new code to perpetuate the habit.
Post reply on HN