[Python-Dev] [Python-checkins] cpython: Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl

Petri Lehtinen petri at digip.org
Wed May 25 07:59:26 CEST 2011


Terry Reedy wrote:
> On 5/24/2011 12:06 PM, Victor Stinner wrote:
> >Le mardi 24 mai 2011 à 11:27 -0400, Terry Reedy a écrit :
> >>>
> >>>+.. function:: RAND_bytes(num)
> >>>+
> >>>+   Returns *num* cryptographically strong pseudo-random bytes.
> >>>+
> >>>+   .. versionadded:: 3.3
> >>>+
> >>>+.. function:: RAND_pseudo_bytes(num)
> >>>+
> >>>+   Returns (bytes, is_cryptographic): bytes are *num* pseudo-random bytes,
> >>>+   is_cryptographic is True if the bytes generated are cryptographically
> >>>+   strong.
> >>>+
> >>>+   .. versionadded:: 3.3
> >>
> >>I am curious what 'cryptographically strong' means, what the real
> >>difference is between the above two functions, and how these do not
> >>duplicate what is in random.random.
> >
> >An important feature of a CPRNG (cryptographic pseudo-random number
> >generator) is that even if you know all of its output, you cannot
> >rebuild its internal state to guess next (or maybe previous number). The
> >CPRNG can for example hash its output using SHA-1: you will have to
> >"break" the SHA-1 hash (maybe using "salt").
> 
> So it is presumably slower. I still do not get RAND_pseudo_bytes,
> which somehow decides internally what to do.

According to the RAND_bytes manual page from OpenSSL:

    RAND_bytes() puts num cryptographically strong pseudo-random
    bytes into buf. An error occurs if the PRNG has not been seeded
    with enough randomness to ensure an unpredictable byte
    sequence.

    RAND_pseudo_bytes() puts num pseudo-random bytes into buf.
    Pseudo-random byte sequences generated by RAND_pseudo_bytes() will
    be unique if they are of sufficient length, but are not
    necessarily unpredictable. They can be used for non-cryptographic
    purposes and for certain purposes in cryptographic protocols, but
    usually not for key generation etc.

And:

    RAND_bytes() returns 1 on success, 0 otherwise. The error code can
    be obtained by ERR_get_error(3). RAND_pseudo_bytes() returns 1 if
    the bytes generated are cryptographically strong, 0 otherwise.
    Both functions return -1 if they are not supported by the current
    RAND method.

So it seems to me that RAND_bytes() either returns cryptographically
strong data or fails (is it possible to detect the failure with the
Python function? Should this be documented?). RAND_pseudo_bytes()
always succeeds but does not necessarily generate cryptographically
strong data.

> 
> > Another important feature is that even if you know the internal state,
> >you will not be able to guess all previous and next numbers, because the
> >internal state is regulary updated using an external source of entropy.
> >Use RAND_add() to do that explicitly.
> >
> >We may add a link to Wikipedia:
> >http://en.wikipedia.org/wiki/CPRNG
> 
> That would be helpful
> >
> >Read the "Requirements" section, it's maybe more correct than my
> >explanation:
> >http://en.wikipedia.org/wiki/CPRNG#Requirements
> >
> >About the random module, it must not be used to generate passwords or
> >certificates, because it is easy to rebuild the internal state of a
> >Mersenne Twister generator if you know the previous 624 numbers. Since
> >you know the state, it's also easy to generate all next numbers. Seed a
> >Mersenne Twister PRNG doesn't help. See my Hasard project if you would
> >like to learn more about PRNG ;-)
> >
> >We may also add a link from random to SSL.RAND_bytes() and
> >SSL.RAND_pseudo_bytes().

Obviously, the user needs to be familiar with the concept of
"cryptographically strong randomness" to use these functions.

Petri Lehtinen


More information about the Python-Dev mailing list