[Python-checkins] cpython: Documentation for secrets.py

steven.daprano python-checkins at python.org
Sat Apr 16 11:44:07 EDT 2016


https://hg.python.org/cpython/rev/3bb3e6316098
changeset:   101017:3bb3e6316098
user:        Steven D'Aprano <steve at pearwood.info>
date:        Sun Apr 17 01:42:33 2016 +1000
summary:
  Documentation for secrets.py

files:
  Doc/library/crypto.rst  |    1 +
  Doc/library/random.rst  |    3 +-
  Doc/library/secrets.rst |  199 ++++++++++++++++++++++++++++
  3 files changed, 202 insertions(+), 1 deletions(-)


diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst
--- a/Doc/library/crypto.rst
+++ b/Doc/library/crypto.rst
@@ -16,3 +16,4 @@
 
    hashlib.rst
    hmac.rst
+   secrets.rst
diff --git a/Doc/library/random.rst b/Doc/library/random.rst
--- a/Doc/library/random.rst
+++ b/Doc/library/random.rst
@@ -46,7 +46,8 @@
 .. warning::
 
    The pseudo-random generators of this module should not be used for
-   security purposes.
+   security purposes.  For security or cryptographic uses, see the
+   :mod:`secrets` module.
 
 
 Bookkeeping functions:
diff --git a/Doc/library/secrets.rst b/Doc/library/secrets.rst
new file mode 100644
--- /dev/null
+++ b/Doc/library/secrets.rst
@@ -0,0 +1,199 @@
+:mod:`secrets` --- Generate secure random numbers for managing secrets
+======================================================================
+
+.. module:: secrets
+   :synopsis: Generate secure random numbers for managing secrets.
+
+.. moduleauthor:: Steven D'Aprano <steve+python at pearwood.info>
+.. sectionauthor:: Steven D'Aprano <steve+python at pearwood.info>
+.. versionadded:: 3.6
+
+.. testsetup::
+
+   from secrets import *
+   __name__ = '<doctest>'
+
+**Source code:** :source:`Lib/secrets.py`
+
+-------------
+
+The :mod:`secrets` module is used for generating cryptographically strong
+random numbers suitable for managing data such as passwords, account
+authentication, security tokens, and related secrets.
+
+In particularly, :mod:`secrets` should be used in preference to the
+default pseudo-random number generator in the :mod:`random` module, which
+is designed for modelling and simulation, not security or cryptography.
+
+.. seealso::
+
+   :pep:`506`
+
+
+Random numbers
+--------------
+
+The :mod:`secrets` module provides access to the most secure source of
+randomness that your operating system provides.
+
+.. class:: SystemRandom
+
+   A class for generating random numbers using the highest-quality
+   sources provided by the operating system.  See
+   :class:`random.SystemRandom` for additional details.
+
+.. function:: choice(sequence)
+
+   Return a randomly-chosen element from a non-empty sequence.
+
+.. function:: randbelow(n)
+
+   Return a random int in the range [0, *n*).
+
+.. function:: randbits(k)
+
+   Return an int with *k* random bits.
+
+
+Generating tokens
+-----------------
+
+The :mod:`secrets` module provides functions for generating secure
+tokens, suitable for applications such as password resets,
+hard-to-guess URLs, and similar.
+
+.. function:: token_bytes([nbytes=None])
+
+   Return a random byte string containing *nbytes* number of bytes.
+   If *nbytes* is ``None`` or not supplied, a reasonable default is
+   used.
+
+   .. doctest::
+
+      >>> token_bytes(16)  #doctest:+SKIP
+      b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
+
+
+.. function:: token_hex([nbytes=None])
+
+   Return a random text string, in hexadecimal.  The string has *nbytes*
+   random bytes, each byte converted to two hex digits.  If *nbytes* is
+   ``None`` or not supplied, a reasonable default is used.
+
+   .. doctest::
+
+      >>> token_hex(16)  #doctest:+SKIP
+      'f9bf78b9a18ce6d46a0cd2b0b86df9da'
+
+.. function:: token_urlsafe([nbytes=None])
+
+   Return a random URL-safe text string, containing *nbytes* random
+   bytes.  The text is Base64 encoded, so on average, each byte results
+   in approximately 1.3 characters.  If *nbytes* is ``None`` or not
+   supplied, a reasonable default is used.
+
+   .. doctest::
+
+      >>> token_urlsafe(16)  #doctest:+SKIP
+      'Drmhze6EPcv0fN_81Bj-nA'
+
+
+How many bytes should tokens use?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To be secure against
+`brute-force attacks <https://en.wikipedia.org/wiki/Brute-force_attack>`_,
+tokens need to have sufficient randomness.  Unfortunately, what is
+considered sufficient will necessarily increase as computers get more
+powerful and able to make more guesses in a shorter period.  As of 2015,
+it is believed that 64 bytes (512 bits) of randomness is sufficient for
+the typical use-case expected for the :mod:`secrets` module.
+
+For those who want to manage their own token length, you can explicitly
+specify how much randomness is used for tokens by giving an :class:`int`
+argument to the various ``token_*`` functions.  That argument is taken
+as the number of bytes of randomness to use.
+
+Otherwise, if no argument is provided, or if the argument is ``None``,
+the ``token_*`` functions will use a reasonable default instead.
+
+.. note::
+
+   That default is subject to change at any time, including during
+   maintenance releases.
+
+
+Other functions
+---------------
+
+.. function:: compare_digest(a, b)
+
+   Return ``True`` if strings *a* and *b* are equal, otherwise ``False``,
+   in such a way as to redice the risk of
+   `timing attacks <http://codahale.com/a-lesson-in-timing-attacks/>`_ .
+   See :func:`hmac.compare_digest` for additional details.
+
+
+Recipes and best practices
+--------------------------
+
+This section shows recipes and best practices for using :mod:`secrets`
+to manage a basic level of security.
+
+Generate an eight-character alphanumeric password:
+
+.. testcode::
+
+   import string
+   alphabet = string.ascii_letters + string.digits
+   password = ''.join(choice(alphabet) for i in range(8))
+
+
+.. note::
+
+   Applications should
+   `not store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_ ,
+   whether plain text or encrypted.  They should always be salted and
+   hashed using a cryptographically-strong one-way (irreversible) hash
+   function.
+
+
+Generate a ten-character alphanumeric password with at least one
+lowercase character, at least one uppercase character, and at least
+three digits:
+
+.. testcode::
+
+   import string
+   alphabet = string.ascii_letters + string.digits
+   while True:
+       password = ''.join(choice(alphabet) for i in range(10))
+       if (any(c.islower() for c in password)
+               and any(c.isupper() for c in password)
+               and sum(c.isdigit() for c in password) >= 3):
+           break
+
+
+Generate an `XKCD-style passphrase <http://xkcd.com/936/>`_ :
+
+.. testcode::
+
+   # On standard Linux systems, use a convenient dictionary file.
+   # Other platforms may need to provide their own word-list.
+   with open('/usr/share/dict/words') as f:
+       words = [word.strip() for word in f]
+       password = ' '.join(choice(words) for i in range(4))
+
+
+Generate a hard-to-guess temporary URL containing a security token
+suitable for password recovery applications:
+
+.. testcode::
+
+   url = 'https://mydomain.com/reset=' + token_urlsafe()
+
+
+
+..
+   # This modeline must appear within the last ten lines of the file.
+   kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8;

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


More information about the Python-checkins mailing list