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([
salt,
str(time()).encode('ascii'),
_urandom()
])).hexdigest()
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?