217

Lets say I want to create a cookie for a user. Would simply generating a 1024 bit string by using /dev/urandom, and checking if it already exists (looping until I get a unique one) suffice?

Should I be generating the key based on something else? Is this prone to an exploit somehow?

13
  • 4
    Checking for uniqueness is slow. A better choice is to ensure uniqueness. Append the time stamp to the string, down as far as you can. This will ensure that no two strings are ever the same, even if somehow the randomness is the same.
    – DampeS8N
    Commented Sep 16, 2011 at 20:40
  • 33
    @DampeS8N You're assuming that repeatedly retrieving a timestamp yields a monotonically increasing value. This is far from true: the timestamp can remain constant during a fast sequence of operations, and can go backwards because the clock is reset for some reason. (Recommended reading: Cryptography Engineering ch. 16.) A counter is a reliable (and fast) way of ensuring uniqueness, if you can store it in non-volatile memory. A crypto-quality (P)RNG does ensure (crypto-quality) uniqueness, no additional technique is needed. Commented Oct 4, 2011 at 20:40
  • 10
    @DampeS8N If /dev/urandom gives you repeats, you have a security problem that merely appending a counter won't fix. As our conversation is wandering away from the question, I suggest that we take any continuation to Information Security Chat(chat.stackexchange.com/rooms/info/151). Commented Oct 4, 2011 at 21:34
  • 43
    All this seems academic. The probability of randomly generating two identical 1024 bit messages is so absurdly low that it doesn't even bear consideration. Commented Oct 25, 2011 at 3:04
  • 10
    @Pacerier If we're the only intelligent beings in the universe, then each failure to check incurs an average of 6e9 / 2^512 = 4.5e-145 deaths. There's not even an SI suffix for a number that small. We should focus on higher risk activities, like being struck by lightning from a clear sky while skydiving on the day you win the lottery. Commented Dec 12, 2014 at 13:01

4 Answers 4

264

The short answer is yes. The long answer is also yes. /dev/urandom yields data which is indistinguishable from true randomness, given existing technology. Getting "better" randomness than what /dev/urandom provides is meaningless, unless you are using one of the few "information theoretic" cryptographic algorithm, which is not your case (you would know it).

The man page for urandom is somewhat misleading, arguably downright wrong, when it suggests that /dev/urandom may "run out of entropy" and /dev/random should be preferred; the only instant where /dev/urandom might imply a security issue due to low entropy is during the first moments of a fresh, automated OS install; if the machine booted up to a point where it has begun having some network activity then it has gathered enough physical randomness to provide randomness of high enough quality for all practical usages (I am talking about Linux here; on FreeBSD, that momentary instant of slight weakness does not occur at all). On the other hand, /dev/random has a tendency of blocking at inopportune times, leading to very real and irksome usability issues. Or, to say it in less words: use /dev/urandom and be happy; use /dev/random and be sorry.

(Edit: this Web page explains the differences between /dev/random and /dev/urandom quite clearly.)

For the purpose of producing a "cookie": such a cookie should be such that no two users share the same cookie, and that it is computationally infeasible for anybody to "guess" the value of an existing cookie. A sequence of random bytes does that well, provided that it uses randomness of adequate quality (/dev/urandom is fine) and that it is long enough. As a rule of thumb, if you have less than 2n users (n = 33 if the whole Earth population could use your system), then a sequence of n+128 bits is wide enough; you do not even have to check for a collision with existing values: you will not see it in your lifetime. 161 bits fits in 21 bytes.

There are some tricks which are doable if you want shorter cookies and still wish to avoid looking up for collisions in your database. But this should hardly be necessary for a cookie (I assume a Web-based context). Also, remember to keep your cookies confidential (i.e. use HTTPS, and set the cookie "secure" and "HttpOnly" flags).

13
  • 3
    On the topic of urandom "running out", you're only sort of right. On a system with a poor entropy source (such as a VM) and a high rate of entropy use (lots of SSH connections, VPN tunnels, etc), urandom will return less random data instead of blocking. "Less random" is a loose term, but it means that you're more likely to see repetition. Is that a problem? Matters on your application :) In this case, urandom is probably fine.
    – Bill Weiss
    Commented May 26, 2011 at 14:40
  • 32
    @Bill, that is not correct. The chances of seeing repetition from /dev/urandom, due to high use of entropy, are essentially nil. (To be precise, by "repetition" I mean an amount of repetition that is statistically significantly higher than expected by chance.) There is essentially no risk that /dev/urandom ever "runs out" within your lifetime.
    – D.W.
    Commented May 27, 2011 at 6:20
  • 6
    You might want to watch the talk "Fast Internet-wide Scanning and its Security Applications" given by J. Alex Halderman at 30C3. They did a large scan for SSH keys and basically found many duplicate keys. It turns out that many devices were embedded systems (like routers) which lack good sources of entropy (mouse, keyboard, etc.) and will usually generate the SSH key right after the boot. They determined that for /dev/urandom there is an "entropy gap" which can take 60 seconds (!) after the system startup, during which the output is actually predictable.
    – dog
    Commented Feb 6, 2014 at 22:05
  • 7
    @dog Before the CSPRNG has been seeded by enough entropy, its output will always be predictable, no matter how little data you read. Once it has been seeded with enough entropy, it will never be (practically) predictable no matter how much data you read. "Running out of entropy" isn't a thing. (CSPRNGs do have theoretical limits about how much data can be generated without a reseed, but you'll never hit them unless the CSPRNG in question sucks.) Commented Apr 19, 2014 at 5:22
  • 9
    There is no contradiction (also, Schneier is merely quoting an article written by other people). The research paper worries about recovering from an internal state compromise, an already rotten situation. If your system was utterly compromised, you should have nuked it from orbit, rather than keeping on generating keys with it; what the article says is that if you do the wrong thing (keep on using the compromised machine "as is" and pray for the best) then the PRNG used in /dev/random (and urandom) won't save your skin -- but, realistically, nothing would have. Commented Dec 12, 2014 at 12:31
27

Yes, it's a great way.

@Thomas's explanation nails it. And he is completely right to criticize the /dev/urandom man page. Spot on.

But skip "checking if it already exists". That check is pointless. It ain't gonna happen. (The chances of that happening are lower than the probability of being struck by lightning -- multiple times -- in the same day.)

2
1

Be aware of edge-cases if you're using Linux or NetBSD.

On Linux, you'd want make sure that enough entropy has been gained after boot to properly seed the CSPRNG, or use the getrandom() system call to read from /dev/urandom and only block in the rare event that sufficient post-boot initial seed entropy is unavailable.

In NetBSD, you'd want to read from /dev/random at least once before reading from /dev/urandom to ensure it has been seeded properly.

On FreeBSD and MacOS there is no difference between /dev/random and /dev/urandom.

The short answer is still to use /dev/urandom.

See When to use /dev/random vs /dev/urandom for further details.

-4

From http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt "Generating true entropy in a computer is fairly difficult because nothing, outside of quantum physics, is random. The Linux kernel uses keyboard, mouse, network, and disc activities, with a cryptographic algorithm (SHA1), to generate data for the /dev/random device. One of the problems with this is that the input is not constant, so the kernel entropy pool can easily become empty." "Another problem with using the keyboard, mouse, network, and disc activity is that on idle, unmanned, and disc-less systems there is very little, or no, input of this kind."

To me it looks real possible that /dev/urandom will run out because /dev/random feeds it.

10
  • 7
    Did you read Thomas's answer? If so, why do you think it's wrong? Commented Aug 13, 2013 at 22:29
  • 4
    Thomas's point seems to be that /dev/urandom "running out of entropy" just isn't a problem. It continues to generate random bytes by other means, but in practice that doesn't affect predictability. I don't know enough about the issues to judge whether he's correct (though what he says agrees with things I've read elsewhere). Do you have specific evidence (or solid theory) that suggests draining the entropy pool is a real problem for /dev/urandom? Code that actually predicts the output of /dev/urandom with better results than chance would be good evidence. Commented Aug 15, 2013 at 20:32
  • 4
    "/dev/urandom uses small amounts of data from /dev/random to seed a secondary entropy pool. This has the effect of inflating the real entropy so it can be conserved. Using /dev/urandom can cause /dev/random's pool to become empty, but if this happens /dev/urandom will not block, and it will continue using the last available seed. This makes /dev/urandom theoretically vulnerable to outputting repeating data, depending on the limitations of the algorithm used, but this is extremely rare and to my knowledge has never actually happened.
    – Buktop
    Commented Aug 20, 2013 at 20:10
  • 3
    /dev/urandom is widely considered safe for all cryptographic purposes, except by the most paranoid people."
    – Buktop
    Commented Aug 20, 2013 at 20:11
  • 6
    Your recent comments almost seem to contradict your answer. Commented Aug 20, 2013 at 20:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .