Checked the cpython source code for both secrets and uuid4. Both seems to be using os.urandom.
#uuid.py
def uuid4():
"""Generate a random UUID."""
return UUID(bytes=os.urandom(16), version=4)
#secrets.py
def token_bytes(nbytes=None):
"""Return a random byte string containing *nbytes* bytes.
If *nbytes* is ``None`` or not supplied, a reasonable
default is used.
>>> token_bytes(16) #doctest:+SKIP
b'\\xebr\\x17D*t\\xae\\xd4\\xe3S\\xb6\\xe2\\xebP1\\x8b'
"""
if nbytes is None:
nbytes = DEFAULT_ENTROPY
return _sysrand.randbytes(nbytes)
# This is code for randbytes in SystemRandom in random
def randbytes(self, n):
"""Generate n random bytes."""
# os.urandom(n) fails with ValueError for n < 0
# and returns an empty bytes string for n == 0.
return _urandom(n)
IETF warns not to use uuid's for security capabilities. Refer section 6 UUID. It says
- Security Considerations
Do not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access), for example. A predictable random number source will exacerbate the situation.
If secrets really does use urandom same as uuid4, can we use uuid4 instead of secrets. What's the whole purpose of using secrets token_bytes instead of uuid4 itself?. As per IETF's standards is secrets module for api keys/tokens really not secure?