Python Random Generators

From UVOO Tech Wiki
Jump to navigation Jump to search

Good information to know to set the mind at ease.

ref: https://stackoverflow.com/questions/42190663/questions-about-python3-6-os-urandom-os-getrandom-secrets

os.getrandom is a wrapper for getrandom() syscall offered in Linux Kernel 3.17 and newer. The flag is a number (0, 1, 2 or 3) that corresponds to bitmask in following way:

os.getrandom(32, flags=0)
GRND_NONBLOCK =  0  (=block when urandom has less than 128 bits of entropy)
GRND_RANDOM   = 0   (=use /dev/urandom)
              = 00  (=flag 0)
This is a good default to use with all Python 3.6 programs when no backwards compatibility with Python 3.5 is needed.

os.getrandom(32, flags=1)
GRND_NONBLOCK =  1  (=never block. Insecure on fresh installs / live distros.)
GRND_RANDOM   = 0   (=use /dev/urandom)
              = 01  (=flag 1)
This is only available when the more secure option (flags=0) is available. It's highly unlikely you will ever need to use this.

os.getrandom(32, flags=2)
GRND_NONBLOCK =  0  (=return 32 bytes or less if entropy_avail counter is low)
GRND_RANDOM   = 1   (=use /dev/random)
              = 10  (=flag 2)
This needs an external loop that runs the function and stores returned bytes into buffer until the buffer size is 32 bytes. In terms of security when live distro is used, flags=0 will return 32 bytes when CSPRNG internal state has collected 16 bytes of entropy. The loop polling os.getrandom(flags=2) will have 32 bytes of entropy in buffer when CSPRNG internal state has 32 bytes so in that case flags=2 is more secure. With sufficiently seeded systems however, /dev/random is not more secure.

os.getrandom(32, flags=3)
GRND_NONBLOCK =  1  (=raise BlockingIOError if not enough entropy is available)
GRND_RANDOM   = 1   (=use /dev/random)
              = 11  (=flag 3)
Useful if the application needs to do other tasks while it waits for entropy pool to have full amount of entropy available. This however might block the function that needs the entropy indefinitely because other programs might load entropy from /dev/random once entropy_avail is high enough. So it might be better to use flags=2 and store entropy into buffer.

os.urandom(32)
Python3.6
Wrapper" for os.getrandom. On Linux 3.17 and newer, it's the equivalent of os.getrandom(32, flags=0), on older kernels quietly falls back to the equivalent of os.getrandom(32, flags=1).

Python3.5 and earlier
Always the equivalent of os.getrandom(32, flags=1)

os.urandom(n) provides best effort security and should only be used for programs that are never to be run from a live distro / fresh install.

secrets.token_bytes(32)
Wrapper for os.urandom() for Python3.6 above. When length argument is omitted, defaults to 32.