> I'm aware of /dev/urandom being non-blocking, but my understanding of
> /dev/urandom is that it is not cryptographicaly secure. 
...
> Any thoughts on that?

[perhaps more thoughts than anyone here cares to hear, but what 
the heck]

You only have so much entropy that's available on a given machine at a
given time. From the same manpage, you can see that if you have access 
to more entropy than /dev/random knows about normally, you can write it 
back to /dev/random (they give an example) but at the end of the day, 
you need to decide -- is it more important that the SessionIDs be safe 
from an opponent with vast computational and/or intercept capabilities, 
or is it more important to not block. My guess is that in the vast 
majority of cases it's more important to not block.

/dev/urandom is going to do as good of a job of stretching the 
available entropy as any other computationally reasonable approach
that you could implement. My summary of the criticism of 
/dev/urandom is that it might not be a hot idea to use it to 
generate a long-lived private/public key pair, but I can't see how
you can do any better if you need a long, reliable stream of
randomness (e.g. a whole bunch of hard-to-predict SessionIDs.)

Here's this from the source code of linux/drivers/char/random.c:

 * When random bytes are desired, they are obtained by taking the SHA
 * hash of the contents of the "entropy pool".  The SHA hash avoids
 * exposing the internal state of the entropy pool.  It is believed to
 * be computationally infeasible to derive any useful information
 * about the input of SHA from its output.  Even if it is possible to
 * analyze SHA in some clever way, as long as the amount of data
 * returned from the generator is less than the inherent entropy in
 * the pool, the output data is totally unpredictable.  For this
 * reason, the routine decreases its internal estimate of how many
 * bits of "true randomness" are contained in the entropy pool as it
 * outputs random numbers.
 * 
 * If this estimate goes to zero, the routine can still generate
 * random numbers; however, an attacker may (at least in theory) be
 * able to infer the future output of the generator from prior
 * outputs.  This requires successful cryptanalysis of SHA, which is
 * not believed to be feasible, but there is a remote possibility.
 * Nonetheless, these numbers should be useful for the vast majority
 * of purposes.

Let's think about how someone might attack a weakness in a SessionID
generator. Assume that the victim computer's version of Linux has a
bug that causes /dev/urandom to be seeded with all zeroes every time
it boots, and that it never adds any entropy. If the opponent guessed
or knew that this was the case, then the opponent could connect to
the webserver, get a SessionID, and would then be able to make very 
good guesses about what other SessionIDs were currently in use. (By
starting from all zeroes, and applying the algorithm until the 
obtained SessionID was reached.)

Assuming that some sort of "entropy" is being added, the next thing
the attacker could do is to come up with a way to either 
predict what is being added as "entropy", or at least guess at it
with substantially more effectiveness than random chance. 

One early version of this many years ago was when Ian Goldberg
and Dave Wagner discovered that an early version of Netscape's
web server was seeding their random number generator with nothing
more than the time and the PID, both of which were sufficiently
easy to guess at that it was quite easy to predict what session
keys would be generated. 

However, unless the attacker has successfully cryptanalyzed SHA
(which would have far greater consequences than the ability to 
predict SessionIDs in Tomact :-) the attacker is going to have 
to successfully model ALL entropy ever added in. After the first
eighty or so bits of "real entropy," it's going to be easier to
just guess random SessionIDs (with some cleverness about 
predicting the time and the session counter, which are both
predictable and inter-related)

Note that the chance of guessing _a_ session (as opposed to a 
particular session) goes up steadily with the total number of
valid sessions. (Let's say, for the sake of example, that you
have a 1/2^80 chance of guessing a particular session; if you
have 2048 valid sessions, it improves to a 1/2^69 chance.) For
this reason, if you're really paranoid, you'll want to increase
the part of the SessionID from /dev/urandom to 128 bits and 
ditch the use of the time (unless it has semantic value down 
the food chain that I'm missing.) This way, as long as you have
more than 128 bits of "real entropy", it's going to be "easier"
for the attacker to make the on average num_sessions/2^127 
guesses needed to find a valid SessionID.

Hope this is helpful!

Cheers,

Doug


Reply via email to