I'm implementing a one-time token service. Each of these one-time token represents some server side data/action associated with it (a 'email confirm' action for example), so that my web service can verify and take action when receiving them without session. (from inside a email's confirm link; from a qr code scan; ...)

These token should be very hard to guess or forge. So i think a long random string (from /dev/urandom) should be well enough. But from https://en.wikipedia.org/wiki//dev/random:

A counterpart to /dev/random is /dev/urandom ("unlimited"[5]/non-blocking random source[4]) which reuses the internal pool to produce more pseudo-random bits. This means that the call will not block, but the output may contain less entropy than the corresponding read from /dev/random. While /dev/urandom is still intended as a pseudorandom number generator suitable for most cryptographic purposes, some people claim /dev/urandom as not recommended[who?] for the generation of long-term cryptographic keys. However this is in general not the case because once the entropy pool is unpredictable it doesn't leak security by a reduced number of bits.

And also i have read some code in werkzeug's session https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/contrib/sessions.py

def _urandom():
    if hasattr(os, 'urandom'):
        return os.urandom(30)
    return text_type(random()).encode('ascii')

def generate_key(salt=None):
    if salt is None:
        salt = repr(salt).encode('ascii')
    return sha1(b''.join([

So my question is: Is such hash(time()+urandom()) generate more 'random' string than pure urandom()? What is the purpose to use a hash function here?

1 Answer 1


Real random data are 100% unpredictable. Interfaces like urandom additionally provide uniform distribution on top of this, i.e. you get not only unpredictable random values but all values have the same probability. If you already have such a high quality source of randomness then hashing will not improve it any more, i.e. hash(time()+urandom()) will not be better than urandom() alone.

But the code example you have falls back to the simple random() function if urandom() is not available. This is usually only a fast pseudo random number generator where the values are somehow predictable if you know enough of the previous values. Thus hashing the output together with a salt and the time might be an attempt to make the output less predictable when faced with a pseudo random number generator only. And while it does not really add more randomness to the output, it makes it harder to get back to the original pseudo random value and thus makes it harder to use attacks against the underlying pseudo random number generator. For real random data you don't need such kind of protection because the input data are fully unpredictable already and there is no way to compute the next random value if the previous ones are known.

  • 3
    As Steffen said, it does not add any entropy, but it helps against reconstructing the state of a weak pseudorandom generator. Note that unpredictability != randomness. For this usage scenario you actually don't need any real randomness at all. You can also pick a sufficiently long passphrase, then just add a count / unique database key / ... and hash the result.
    – numo68
    Jan 3, 2016 at 14:07
  • Steffen - your first sentence confuses me. Looks like a typo or something. Can you tweak it? Jan 3, 2016 at 16:55
  • As a stray thought, in the unlikely event that SHA1 turns out not to be surjective, the hashing might reduce the randomness of /dev/urandom. Jan 3, 2016 at 17:04
  • @numo68 What is the difference between unpredictability and randomness ?
    – jayven
    Jan 4, 2016 at 0:21
  • 1
    @jayven: Not everything which is unpredictable is random - it might just be too hard to compute in an acceptable time. But everything which is truly random is unpredictable. Jan 4, 2016 at 5:30

You must log in to answer this question.

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