

How to safely generate a random number - e1ven
http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/

======
weavejester
So rather than using a function in the core library of the language that calls
/dev/urandom, we should instead write our own wrapper around /dev/urandom? And
this is supposed to be less prone to error?

~~~
SamReidHughes2
Where does this article say that?

~~~
jbaudanza
The article lists several userspace libraries (OpenSSL, SecureRandom) and then
says not to use them. I had the same question as weavejester.

~~~
tptacek
No. OpenSSL RAND_bytes and Java SecureRandom aren't simply libraries that
"call /dev/urandom"; they are full-fledged CSPRNG designs, and must themselves
avoid all the possible bugs a CSPRNG can have, in addition to their usual
reliance on urandom not itself being vulnerable.

~~~
weavejester
The NativePRNG algorithm for SecureRandom XORs /dev/urandom with a SHA1PRNG
seeded from /dev/urandom, so as long as the XOR is correct, it should be no
less secure than reading from /dev/urandom directly.

~~~
tptacek
I would definitely avoid Java's SecureRandom. It means too many different
things depending on what platform you're on. Meanwhile, XORing SHA1PRNG
against /dev/urandom seems cryptographically nonsensical.

~~~
TheLoneWolfling
> XORing SHA1PRNG against /dev/urandom seems cryptographically nonsensical.

Untrue! Assuming that the two (/dev/urandom and SHA1PRNG) are not correlated,
the resulting output will be at least as secure as the most secure of the two.
This means that (for example) if SHA1PRNG is found to be breakable,
SecureRandom will still be at least as secure as /dev/urandom, and vice versa.

~~~
tptacek
This is a rabbit hole I don't want to go down and so I will concede the point
about NativePRNG, while sticking to my guns on "avoid the Java SecureRandom
interface".

------
eliteraspberrie
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.urandom, which is a wrapper to the system's
CSPRNG. Don't use random.randint or random.getrandbits...

~~~
pbsd
> The randombytes function in NaCl does it right, unfortunately libsodium did
> their own thing.

I don't know what you're talking about. Sodium does the same thing as NaCl,
while also being more portable.

~~~
eliteraspberrie
No, libsodium does not do the same thing as NaCl.

NaCl:

[https://gist.github.com/anonymous/9234738](https://gist.github.com/anonymous/9234738)

libsodium:

[https://github.com/jedisct1/libsodium/blob/master/src/libsod...](https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c)

~~~
pbsd
I'm aware that the implementations are not strictly equal, but how is
libsodium doing it 'wrong'? Is it because it does not partition reads into
smaller chunks (avoiding the unspecified >= SSIZE_MAX read)? I consider any
reasonable answer a valid bug report.

I should also point out that randombytes is technically not part of NaCl. The
authors maintain that random byte generation is out of scope for NaCl, and
what actually happens is that randombytes.o is bundled separately from
libnacl.a [1]. In TweetNacl the randombytes implementation is completely
omitted.

[1] [https://bugs.debian.org/cgi-
bin/bugreport.cgi?msg=20;bug=694...](https://bugs.debian.org/cgi-
bin/bugreport.cgi?msg=20;bug=694248#20)

~~~
eliteraspberrie
Don't take my word for it, check libsodium with Frama-C (as NaCl was) and file
the bug report yourself.

------
csense
I prefer the Munroe-Hatguy entropy collection method for pseudorandom number
generation [1].

[1] [http://xkcd.com/221/](http://xkcd.com/221/)

~~~
marshray
I knew that link was going to show up. It's predictable that way.

------
luke-stanley
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_...](https://www.schneier.com/blog/archives/2013/10/insecurities_in.html#c1909001)

Is that out of date?

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

~~~
tptacek
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.

~~~
luke-stanley
How do we know there isn't some predictable pattern from common urandom
sources? What is meant to make the state non-predictable anyway? If I cared
about it, someone could just add a library on top of it that combines them
with more entropy sources. Like camera noise, temperature changes, audio
static etc. For some reason the author says not to build libraries on top of
urandom because they might be hacked. Well if something has compromised your
system anyway, why does that matter?

~~~
tptacek
"The urandom sources"? What do you think that means? The code is right there.

~~~
luke-stanley
I'm talking about the sources of it's random input, not it's source code.

------
DanBC
> For cryptography, you don’t usually want “true random”.

Wait what? I thought I wanted actually random numbers.

~~~
tptacek
Chapter 9 of _Cryptography Engineering_ leads off with a dozen or so
paragraphs on why crypto software doesn't use real random.

~~~
DanBC
Thank you, I shall do some more (and better) reading.

------
anaphor
What about haveged? Is that good enough for crypto?
[http://www.issihosts.com/haveged/](http://www.issihosts.com/haveged/)

------
ars
/dev/urandom is slow. So don't use it if you need lots of non secure random
numbers. For example for game, or for a screensaver, etc.

~~~
montecarl
If you want fast non-secure random numbers use Mersenne Twister:
[http://en.wikipedia.org/wiki/Mersenne_twister](http://en.wikipedia.org/wiki/Mersenne_twister)

~~~
SamReidHughes2
You can also get much faster secure random numbers.

------
BasicBlock
So, what specifically did Matt Green disagree with?

------
lawnchair_larry
This rant does more harm than good. Telling people not to use a library csprng
is quite silly. Everything uses these and it's fine.

~~~
tptacek
Yeah I mean, there's probably never been a urandom-based vulnerability in
ordinary software, and "library csprngs" are the reason every Debian SSH was
compromised and the reason Android Bitcoin wallets were generating colliding
keys, but sure. Everything's fine.

------
cratermoon
Anyone want to give a total count of wrong assertions in this article?

~~~
tptacek
_popcorn.gif_

------
spartanatreyu
I liked the part that said "urandom".

