Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python's pycrypto library for random number generation vs os.urandom

I was trying to understand and figure out if I should use os.urandom() or Crypto.Random.new() for cryptographically secure pseudo-random numbers.

The following website seems to suggest to use os.urandom():

https://github.com/mozilla/PyHawk/pull/13

but I don't really see why and the other websites I found online don't really explain which one to use.

If anyone knows which one is secure for cryptographic use, I would appreciate the advice!

One of the things that specifically worry me is that, I plan to use it to generate random numbers but I am worried that one day I generate some random numbers and the next day the state of the generator is the same and it starts to generate the same "random" numbers.

like image 290
Charlie Parker Avatar asked Dec 08 '13 22:12

Charlie Parker


People also ask

What is the difference between Dev random and Dev Urandom?

The key difference between /dev/random versus /dev/urandom is whether a threshold of enough entropy has to be reached before random numbers are generated. Reading from /dev/random will be put on hold if the kernel has not gathered enough entropy to provide the requested amount of data.

What is OS Urandom Python?

os. urandom() method is used to generate a string of size random bytes suitable for cryptographic use or we can say this method generates a string containing random characters. Syntax: os.urandom(size) Parameter: size: It is the size of string random bytes.

How random is OS Urandom?

urandom on the other hand cannot be seeded and draws its source of entropy from many unpredictable sources, making it more random.

Does Python have support for random numbers?

The Python standard library provides a module called random that offers a suite of functions for generating random numbers. Python uses a popular and robust pseudorandom number generator called the Mersenne Twister.


2 Answers

I go for os.urandom. On all (recent) Python implementations I checked, it does the correct thing by simply opening an unbuffered connection to /dev/urandom or the equivalent device on other non-Linux platforms.

On the other hand, PyCrypto's Crypto.Random is a very complex wrapper based on Fortuna. Such complex construction was probably done in the hope of mitigating some flaws of the underlying OS. Unfortunately:

  • It still pulls entropy from /dev/urandom (on Linux), so if the OS is broken, PyCrypto's Crypto.Random will be broken too (defeating its purpose)
  • That choice has backfired, since it is very hard to deal with forking and cases where the same entropy gets reused by different processes (see CVE-2013-1445).
  • The Fortuna code is not covered at all by unit tests and Fortuna algorithm itself does not come with test vectors. That alone forces you to make a (big) leap of faith.
like image 72
SquareRootOfTwentyThree Avatar answered Nov 15 '22 18:11

SquareRootOfTwentyThree


In the link you gave, the only reason given to prefer urandom() is that it pulled less code in (the OS implements "most of it", and os.urandom() is built in to Python).

If you're going to distribute a Python package, you can simplify users' lives by minimizing external dependencies. That's the entire point of the link you found.

In terms of quality, either way should work fine. I prefer urandom() because I understand what it does; I never dug into the guts of PyCrypto. But urandom() has been criticized for use in some environments. Click this and scroll down to the part that starts

Gutterman, Pinkas, & Reinman in March 2006 published a detailed cryptographic analysis of the Linux random number generator ...

like image 39
Tim Peters Avatar answered Nov 15 '22 18:11

Tim Peters