1

The secrets module is marketed as a safe alternative to random for things that are meant to be secret. But what's the actual difference? Looking at their code, in some cases these libraries actually make reference to the same underlying functions.

For example, the definition of secrets.randbits is basically a reference to random.getrandbits:

from random import SystemRandom
_sysrand = SystemRandom()
randbits = _sysrand.getrandbits

Another example is secrets.token_bytes which is basically a reference to random.randbytes, which later ends up calling random.getrandbits:

def token_bytes(nbytes=None):
    if nbytes is None:
        nbytes = DEFAULT_ENTROPY
    return _sysrand.randbytes(nbytes)

So what is exactly safer? Is this more of a namespace improvement to keep the community from writing their own token-generating code? PEP 506 is not very clear about this IMHO.

Please note this is not about /dev/urandom and the quality of its entropy.

random
  • 11
  • 1

1 Answers1

0

The motivation is in my opinion pretty clear from PEP 506:

... concerns that Python's standard library makes it too easy for developers to inadvertently make serious security errors ... Although the documentation for the random module explicitly states that the default is not suitable for security purposes [2], it is strongly believed that this warning may be missed, ignored or misunderstood by many Python developers ...

Thus, this is about providing an API which is easy to use and has secure defaults in order to reduce security issues caused by hard to use interfaces with insecure defaults. Therefore this is not a reimplementation, but just an easier and more secure wrapper around existing functionality.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • Thanks for your answer. I see your point but I'm concerned about what makes secrets safer, not their motivation. In that same chapter they write about concerns regarding the usage of MT so I'm assuming secrets does something to address that (otherwise why write about this in the PEP?) but secrets uses MT anyways because it's based on random. The random docs warn "The pseudo-random generators of this module should not be used for security purposes." -- but secrets uses the same generators... so does this mean the numbers generated by secrets shouldn't be used for security purposes? – random Dec 23 '20 at 18:30
  • 1
    @random: Looking at the code it is using `SystemRandom` not `random.random()` for getting the random data. `SystemRandom` is MT safe since it gets the random data from the system and not from some in-process state. – Steffen Ullrich Dec 23 '20 at 18:39
  • Thank you so much. I totally misread random.py. I now see that `SystemRandom` subclasses `Random`. Even though `Random` subclasses Python's C random module (which uses MT), `SystemRandom` overrides `random()` so it uses urandom instead of MT. The `secrets` module uses `SystemRandom`, therefore avoiding MT since `random`, `getrandbits` and `randbytes` all use urandom. – random Dec 23 '20 at 19:46