add discussion on defaults, naming conventions, possible implementations
This commit is contained in:
commit
758b704c4a
140
pep-0506.txt
140
pep-0506.txt
|
@ -50,7 +50,7 @@ errors. Theo de Raadt, the founder of OpenBSD, contacted Guido van Rossum
|
|||
and expressed some concern [1]_ about the use of MT for generating sensitive
|
||||
information such as passwords, secure tokens, session keys and similar.
|
||||
|
||||
Although the documentation for the random module explicitly states that
|
||||
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. In particular:
|
||||
|
@ -58,7 +58,7 @@ many Python developers. In particular:
|
|||
* developers may not have read the documentation and consequently
|
||||
not seen the warning;
|
||||
|
||||
* they may not realise that their specific use of it has security
|
||||
* they may not realise that their specific use of the module has security
|
||||
implications; or
|
||||
|
||||
* not realising that there could be a problem, they have copied code
|
||||
|
@ -140,20 +140,71 @@ The consensus appears to be that there is no need to add a new CSPRNG to
|
|||
the ``random`` module to support these uses, ``SystemRandom`` will be
|
||||
sufficient.
|
||||
|
||||
Some illustrative implementations have been given by Nick Coghlan [10]_.
|
||||
This idea has also been discussed on the issue tracker for the
|
||||
"cryptography" module [11]_.
|
||||
Some illustrative implementations have been given by Nick Coghlan [10]_
|
||||
and a minimalist API by Tim Peters [11]_. This idea has also been discussed
|
||||
on the issue tracker for the "cryptography" module [12]_. The following
|
||||
pseudo-code can be taken as a possible starting point for the real
|
||||
implementation::
|
||||
|
||||
from random import SystemRandom
|
||||
from hmac import compare_digest as equal
|
||||
|
||||
_sysrand = SystemRandom()
|
||||
|
||||
randrange = _sysrand.randrange
|
||||
randint = _sysrand.randint
|
||||
randbits = _sysrand.getrandbits
|
||||
choice = _sysrand.choice
|
||||
|
||||
def randbelow(exclusive_upper_bound):
|
||||
return _sysrand._randbelow(exclusive_upper_bound)
|
||||
|
||||
DEFAULT_ENTROPY = 32 # bytes
|
||||
|
||||
def token_bytes(nbytes=None):
|
||||
if nbytes is None:
|
||||
nbytes = DEFAULT_ENTROPY
|
||||
return os.urandom(nbytes)
|
||||
|
||||
def token_hex(nbytes=None):
|
||||
return binascii.hexlify(token_bytes(nbytes)).decode('ascii')
|
||||
|
||||
def token_url(nbytes=None):
|
||||
tok = token_bytes(nbytes)
|
||||
return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii')
|
||||
|
||||
|
||||
The ``secrets`` module itself will be pure Python, and other Python
|
||||
implementations can easily make use of it unchanged, or adapt it as
|
||||
necessary.
|
||||
|
||||
Default arguments
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
One difficult question is "How many bytes should my token be?". We can
|
||||
help with this question by providing a default amount of entropy for the
|
||||
"token_*" functions. If the ``nbytes`` argument is None or not given, the
|
||||
default entropy will be used. This default value should be large enough
|
||||
to be expected to be secure for medium-security uses, but is expected to
|
||||
change in the future, possibly even in a maintenance release [13]_.
|
||||
|
||||
Naming conventions
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
One question is the naming conventions used in the module [14]_, whether to
|
||||
use C-like naming conventions such as "randrange" or more Pythonic names
|
||||
such as "random_range".
|
||||
|
||||
Functions which are simply bound methods of the private ``SystemRandom``
|
||||
instance (e.g. ``randrange``), or a thin wrapper around such, should keep
|
||||
the familiar names. Those which are something new (such as the various
|
||||
``token_*`` functions) will use more Pythonic names.
|
||||
|
||||
Alternatives
|
||||
============
|
||||
|
||||
One alternative is to change the default PRNG provided by the ``random``
|
||||
module [12]_. This received considerable scepticism and outright opposition:
|
||||
module [15]_. This received considerable scepticism and outright opposition:
|
||||
|
||||
* There is fear that a CSPRNG may be slower than the current PRNG (which
|
||||
in the case of MT is already quite slow).
|
||||
|
@ -172,13 +223,13 @@ module [12]_. This received considerable scepticism and outright opposition:
|
|||
|
||||
* Demonstrated attacks against MT are typically against PHP applications.
|
||||
It is believed that PHP's version of MT is a significantly softer target
|
||||
than Python's version, due to a poor seeding technique [13]_. Consequently,
|
||||
than Python's version, due to a poor seeding technique [16]_. Consequently,
|
||||
without a proven attack against Python applications, many people object
|
||||
to a backwards-incompatible change.
|
||||
|
||||
Nick Coghlan made an earlier suggestion for a globally configurable PRNG
|
||||
which uses the system CSPRNG by default [14]_, but has since hinted that he
|
||||
may withdraw it in favour of this proposal [15]_.
|
||||
which uses the system CSPRNG by default [17]_, but has since withdrawn it
|
||||
in favour of this proposal.
|
||||
|
||||
|
||||
Comparison To Other Languages
|
||||
|
@ -186,7 +237,7 @@ Comparison To Other Languages
|
|||
|
||||
* PHP
|
||||
|
||||
PHP includes a function ``uniqid`` [16]_ which by default returns a
|
||||
PHP includes a function ``uniqid`` [18]_ which by default returns a
|
||||
thirteen character string based on the current time in microseconds.
|
||||
Translated into Python syntax, it has the following signature::
|
||||
|
||||
|
@ -197,7 +248,7 @@ Comparison To Other Languages
|
|||
applications use it for that purpose (citation needed).
|
||||
|
||||
PHP 5.3 and better also includes a function ``openssl_random_pseudo_bytes``
|
||||
[17]_. Translated into Python syntax, it has roughly the following
|
||||
[19]_. Translated into Python syntax, it has roughly the following
|
||||
signature::
|
||||
|
||||
def openssl_random_pseudo_bytes(length:int)->Tuple[str, bool]
|
||||
|
@ -209,16 +260,16 @@ Comparison To Other Languages
|
|||
|
||||
* Javascript
|
||||
|
||||
Based on a rather cursory search [18]_, there doesn't appear to be any
|
||||
Based on a rather cursory search [20]_, there do not appear to be any
|
||||
well-known standard functions for producing strong random values in
|
||||
Javascript, although there may be good quality third-party libraries.
|
||||
Standard Javascript doesn't seem to include an interface to the
|
||||
system CSPRNG either, and people have extensively written about the
|
||||
weaknesses of Javascript's ``Math.random`` [19]_.
|
||||
weaknesses of Javascript's ``Math.random`` [21]_.
|
||||
|
||||
* Ruby
|
||||
|
||||
The Ruby standard library includes a module ``SecureRandom`` [20]_
|
||||
The Ruby standard library includes a module ``SecureRandom`` [22]_
|
||||
which includes the following methods:
|
||||
|
||||
* base64 - returns a Base64 encoded random string.
|
||||
|
@ -240,12 +291,15 @@ What Should Be The Name Of The Module?
|
|||
|
||||
There was a proposal to add a "random.safe" submodule, quoting the Zen
|
||||
of Python "Namespaces are one honking great idea" koan. However, the
|
||||
author of the Zen, Tim Peters, has come out against this idea [21]_, and
|
||||
author of the Zen, Tim Peters, has come out against this idea [23]_, and
|
||||
recommends a top-level module.
|
||||
|
||||
In discussion on the python-ideas mailing list so far, the name "secrets"
|
||||
has received some approval, and no strong opposition.
|
||||
|
||||
There is already an existing third-party module with the same name [24]_,
|
||||
but it appears to be unused and abandoned.
|
||||
|
||||
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
@ -255,9 +309,9 @@ Frequently Asked Questions
|
|||
|
||||
A: The consensus among security professionals is that MT is not safe
|
||||
in security contexts. It is not difficult to reconstruct the internal
|
||||
state of MT [22]_ [23]_ and so predict all past and future values. There
|
||||
state of MT [25]_ [26]_ and so predict all past and future values. There
|
||||
are a number of known, practical attacks on systems using MT for
|
||||
randomness [24]_.
|
||||
randomness [27]_.
|
||||
|
||||
While there are currently no known direct attacks on applications
|
||||
written in Python due to the use of MT, there is widespread agreement
|
||||
|
@ -268,7 +322,7 @@ Frequently Asked Questions
|
|||
A: No. This is a "batteries included" solution, not a full-featured
|
||||
"nuclear reactor". It is intended to mitigate against some basic
|
||||
security errors, not be a solution to all security-related issues. To
|
||||
quote Nick Coghlan referring to his earlier proposal [25]_::
|
||||
quote Nick Coghlan referring to his earlier proposal [28]_::
|
||||
|
||||
"...folks really are better off learning to use things like
|
||||
cryptography.io for security sensitive software, so this change
|
||||
|
@ -276,6 +330,14 @@ Frequently Asked Questions
|
|||
non-trivial proportion of the millions of current and future
|
||||
Python developers won't do that."
|
||||
|
||||
* Q: What about a password generator?
|
||||
|
||||
A: The consensus is that the requirements for password generators are too
|
||||
variable for it to be a good match for the standard library [29]_. No
|
||||
password generator will be included in the initial release of the
|
||||
module, instead it will be given in the documentation as a recipe (à la
|
||||
the recipes in the ``itertools`` module) [30]_.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
@ -305,38 +367,50 @@ References
|
|||
|
||||
.. [10] https://mail.python.org/pipermail/python-ideas/2015-September/036271.html
|
||||
|
||||
.. [11] https://github.com/pyca/cryptography/issues/2347
|
||||
.. [11] https://mail.python.org/pipermail/python-ideas/2015-September/036350.html
|
||||
|
||||
.. [12] Link needed.
|
||||
.. [12] https://github.com/pyca/cryptography/issues/2347
|
||||
|
||||
.. [13] By default PHP seeds the MT PRNG with the time (citation needed),
|
||||
.. [13] https://mail.python.org/pipermail/python-ideas/2015-September/036517.html
|
||||
https://mail.python.org/pipermail/python-ideas/2015-September/036515.html
|
||||
|
||||
.. [14] https://mail.python.org/pipermail/python-ideas/2015-September/036474.html
|
||||
|
||||
.. [15] Link needed.
|
||||
|
||||
.. [16] By default PHP seeds the MT PRNG with the time (citation needed),
|
||||
which is exploitable by attackers, while Python seeds the PRNG with
|
||||
output from the system CSPRNG, which is believed to be much harder to
|
||||
exploit.
|
||||
|
||||
.. [14] http://legacy.python.org/dev/peps/pep-0504/
|
||||
.. [17] http://legacy.python.org/dev/peps/pep-0504/
|
||||
|
||||
.. [15] https://mail.python.org/pipermail/python-ideas/2015-September/036243.html
|
||||
.. [18] http://php.net/manual/en/function.uniqid.php
|
||||
|
||||
.. [16] http://php.net/manual/en/function.uniqid.php
|
||||
.. [19] http://php.net/manual/en/function.openssl-random-pseudo-bytes.php
|
||||
|
||||
.. [17] http://php.net/manual/en/function.openssl-random-pseudo-bytes.php
|
||||
.. [20] Volunteers and patches are welcome.
|
||||
|
||||
.. [18] Volunteers and patches are welcome.
|
||||
.. [21] http://ifsec.blogspot.fr/2012/05/cross-domain-mathrandom-prediction.html
|
||||
|
||||
.. [19] http://ifsec.blogspot.fr/2012/05/cross-domain-mathrandom-prediction.html
|
||||
.. [22] http://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html
|
||||
|
||||
.. [20] http://ruby-doc.org/stdlib-2.1.2/libdoc/securerandom/rdoc/SecureRandom.html
|
||||
.. [23] https://mail.python.org/pipermail/python-ideas/2015-September/036254.html
|
||||
|
||||
.. [21] https://mail.python.org/pipermail/python-ideas/2015-September/036254.html
|
||||
.. [24] https://pypi.python.org/pypi/secrets
|
||||
|
||||
.. [22] https://jazzy.id.au/2010/09/22/cracking_random_number_generators_part_3.html
|
||||
.. [25] https://jazzy.id.au/2010/09/22/cracking_random_number_generators_part_3.html
|
||||
|
||||
.. [23] https://mail.python.org/pipermail/python-ideas/2015-September/036077.html
|
||||
.. [26] https://mail.python.org/pipermail/python-ideas/2015-September/036077.html
|
||||
|
||||
.. [24] https://media.blackhat.com/bh-us-12/Briefings/Argyros/BH_US_12_Argyros_PRNG_WP.pdf
|
||||
.. [27] https://media.blackhat.com/bh-us-12/Briefings/Argyros/BH_US_12_Argyros_PRNG_WP.pdf
|
||||
|
||||
.. [25] https://mail.python.org/pipermail/python-ideas/2015-September/036157.html
|
||||
.. [28] https://mail.python.org/pipermail/python-ideas/2015-September/036157.html
|
||||
|
||||
.. [29] https://mail.python.org/pipermail/python-ideas/2015-September/036476.html
|
||||
https://mail.python.org/pipermail/python-ideas/2015-September/036478.html
|
||||
|
||||
.. [30] https://mail.python.org/pipermail/python-ideas/2015-September/036488.html
|
||||
|
||||
|
||||
Copyright
|
||||
|
|
Loading…
Reference in New Issue