[Python-checkins] peps: Add sample code, default arguments, naming conventions.

steven.daprano python-checkins at python.org
Tue Oct 6 08:11:23 EDT 2015


https://hg.python.org/peps/rev/6de7d0d8d201
changeset:   6106:6de7d0d8d201
parent:      6102:c7712f920a8f
user:        Steven D'Aprano <steve+python at pearwood.info>
date:        Sat Oct 03 21:42:05 2015 +1000
summary:
  Add sample code, default arguments, naming conventions.

files:
  pep-0506.txt |  136 +++++++++++++++++++++++++++++---------
  1 files changed, 103 insertions(+), 33 deletions(-)


diff --git a/pep-0506.txt b/pep-0506.txt
--- a/pep-0506.txt
+++ b/pep-0506.txt
@@ -50,7 +50,7 @@
 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 @@
 * 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,67 @@
 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)
+
+    def token_bytes(nbytes=32):
+        return os.urandom(nbytes)
+
+    def token_hex(nbytes=32):
+        return binascii.hexlify(token_bytes(nbytes)).decode('ascii')
+
+    def token_url(nbytes=32):
+        return base64.urlsafe_b64encode(token_bytes(nbytes)).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 giving the "token_*" functions a sensible default for
+the ``nbytes`` argument. This default value should be large enough to be
+expected to be secure for medium-security uses [xxx]_.
+
+It is expected that future versions will need to increase those default
+values, possibly even during 
+
+Naming conventions
+~~~~~~~~~~~~~~~~~~
+
+One question is the naming conventions used in the module [13]_, 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 [14]_.  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 +219,13 @@
 
 * 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 [15]_.  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 [16]_, but has since withdrawn it
+in favour of this proposal.
 
 
 Comparison To Other Languages
@@ -186,7 +233,7 @@
 
 * PHP
 
-  PHP includes a function ``uniqid`` [16]_ which by default returns a
+  PHP includes a function ``uniqid`` [17]_ 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 +244,7 @@
   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
+  [18]_.  Translated into Python syntax, it has roughly the following
   signature::
 
     def openssl_random_pseudo_bytes(length:int)->Tuple[str, bool]
@@ -209,16 +256,16 @@
 
 * Javascript
 
-  Based on a rather cursory search [18]_, there doesn't appear to be any
+  Based on a rather cursory search [19]_, 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`` [20]_.
 
 * Ruby
 
-  The Ruby standard library includes a module ``SecureRandom`` [20]_
+  The Ruby standard library includes a module ``SecureRandom`` [21]_
   which includes the following methods:
 
   * base64 - returns a Base64 encoded random string.
@@ -240,12 +287,15 @@
 
 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 [22]_, 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 [23]_,
+but it appears to be unused and abandoned.
+
 
 Frequently Asked Questions
 ==========================
@@ -255,9 +305,9 @@
 
   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 [24]_ [25]_ and so predict all past and future values.  There
   are a number of known, practical attacks on systems using MT for
-  randomness [24]_.
+  randomness [26]_.
 
   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 +318,7 @@
   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 [27]_::
 
       "...folks really are better off learning to use things like
       cryptography.io for security sensitive software, so this change
@@ -276,6 +326,14 @@
       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 [28]_. 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) [29]_.
+
 
 References
 ==========
@@ -305,38 +363,50 @@
 
 .. [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),
+.. [xx] See discussion thread starting with
+        https://mail.python.org/pipermail/python-ideas/2015-September/036509.html
+
+.. [13] https://mail.python.org/pipermail/python-ideas/2015-September/036474.html
+
+.. [14] Link needed.
+
+.. [15] 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/
+.. [16] http://legacy.python.org/dev/peps/pep-0504/
 
-.. [15] https://mail.python.org/pipermail/python-ideas/2015-September/036243.html
+.. [17] http://php.net/manual/en/function.uniqid.php
 
-.. [16] http://php.net/manual/en/function.uniqid.php
+.. [18] http://php.net/manual/en/function.openssl-random-pseudo-bytes.php
 
-.. [17] http://php.net/manual/en/function.openssl-random-pseudo-bytes.php
+.. [19] Volunteers and patches are welcome.
 
-.. [18] Volunteers and patches are welcome.
+.. [20] http://ifsec.blogspot.fr/2012/05/cross-domain-mathrandom-prediction.html
 
-.. [19] http://ifsec.blogspot.fr/2012/05/cross-domain-mathrandom-prediction.html
+.. [21] 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
+.. [22] https://mail.python.org/pipermail/python-ideas/2015-September/036254.html
 
-.. [21] https://mail.python.org/pipermail/python-ideas/2015-September/036254.html
+.. [23] https://pypi.python.org/pypi/secrets
 
-.. [22] https://jazzy.id.au/2010/09/22/cracking_random_number_generators_part_3.html
+.. [24] 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
+.. [25] 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
+.. [26] 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
+.. [27] https://mail.python.org/pipermail/python-ideas/2015-September/036157.html
+
+.. [28] https://mail.python.org/pipermail/python-ideas/2015-September/036476.html
+        https://mail.python.org/pipermail/python-ideas/2015-September/036478.html
+
+.. [29] https://mail.python.org/pipermail/python-ideas/2015-September/036488.html
 
 
 Copyright

-- 
Repository URL: https://hg.python.org/peps


More information about the Python-checkins mailing list