17db96d56Sopenharmony_ci:mod:`secrets` --- Generate secure random numbers for managing secrets
27db96d56Sopenharmony_ci======================================================================
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci.. module:: secrets
57db96d56Sopenharmony_ci   :synopsis: Generate secure random numbers for managing secrets.
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci.. moduleauthor:: Steven D'Aprano <steve+python@pearwood.info>
87db96d56Sopenharmony_ci.. sectionauthor:: Steven D'Aprano <steve+python@pearwood.info>
97db96d56Sopenharmony_ci.. versionadded:: 3.6
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci.. testsetup::
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ci   from secrets import *
147db96d56Sopenharmony_ci   __name__ = '<doctest>'
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci**Source code:** :source:`Lib/secrets.py`
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci-------------
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ciThe :mod:`secrets` module is used for generating cryptographically strong
217db96d56Sopenharmony_cirandom numbers suitable for managing data such as passwords, account
227db96d56Sopenharmony_ciauthentication, security tokens, and related secrets.
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ciIn particular, :mod:`secrets` should be used in preference to the
257db96d56Sopenharmony_cidefault pseudo-random number generator in the :mod:`random` module, which
267db96d56Sopenharmony_ciis designed for modelling and simulation, not security or cryptography.
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci.. seealso::
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci   :pep:`506`
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ciRandom numbers
347db96d56Sopenharmony_ci--------------
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ciThe :mod:`secrets` module provides access to the most secure source of
377db96d56Sopenharmony_cirandomness that your operating system provides.
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci.. class:: SystemRandom
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci   A class for generating random numbers using the highest-quality
427db96d56Sopenharmony_ci   sources provided by the operating system.  See
437db96d56Sopenharmony_ci   :class:`random.SystemRandom` for additional details.
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci.. function:: choice(sequence)
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci   Return a randomly chosen element from a non-empty sequence.
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci.. function:: randbelow(n)
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci   Return a random int in the range [0, *n*).
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci.. function:: randbits(k)
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci   Return an int with *k* random bits.
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ciGenerating tokens
597db96d56Sopenharmony_ci-----------------
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ciThe :mod:`secrets` module provides functions for generating secure
627db96d56Sopenharmony_citokens, suitable for applications such as password resets,
637db96d56Sopenharmony_cihard-to-guess URLs, and similar.
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci.. function:: token_bytes([nbytes=None])
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci   Return a random byte string containing *nbytes* number of bytes.
687db96d56Sopenharmony_ci   If *nbytes* is ``None`` or not supplied, a reasonable default is
697db96d56Sopenharmony_ci   used.
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci   .. doctest::
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci      >>> token_bytes(16)  #doctest:+SKIP
747db96d56Sopenharmony_ci      b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci
777db96d56Sopenharmony_ci.. function:: token_hex([nbytes=None])
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ci   Return a random text string, in hexadecimal.  The string has *nbytes*
807db96d56Sopenharmony_ci   random bytes, each byte converted to two hex digits.  If *nbytes* is
817db96d56Sopenharmony_ci   ``None`` or not supplied, a reasonable default is used.
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci   .. doctest::
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci      >>> token_hex(16)  #doctest:+SKIP
867db96d56Sopenharmony_ci      'f9bf78b9a18ce6d46a0cd2b0b86df9da'
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci.. function:: token_urlsafe([nbytes=None])
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci   Return a random URL-safe text string, containing *nbytes* random
917db96d56Sopenharmony_ci   bytes.  The text is Base64 encoded, so on average each byte results
927db96d56Sopenharmony_ci   in approximately 1.3 characters.  If *nbytes* is ``None`` or not
937db96d56Sopenharmony_ci   supplied, a reasonable default is used.
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci   .. doctest::
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci      >>> token_urlsafe(16)  #doctest:+SKIP
987db96d56Sopenharmony_ci      'Drmhze6EPcv0fN_81Bj-nA'
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci
1017db96d56Sopenharmony_ciHow many bytes should tokens use?
1027db96d56Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ciTo be secure against
1057db96d56Sopenharmony_ci`brute-force attacks <https://en.wikipedia.org/wiki/Brute-force_attack>`_,
1067db96d56Sopenharmony_citokens need to have sufficient randomness.  Unfortunately, what is
1077db96d56Sopenharmony_ciconsidered sufficient will necessarily increase as computers get more
1087db96d56Sopenharmony_cipowerful and able to make more guesses in a shorter period.  As of 2015,
1097db96d56Sopenharmony_ciit is believed that 32 bytes (256 bits) of randomness is sufficient for
1107db96d56Sopenharmony_cithe typical use-case expected for the :mod:`secrets` module.
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ciFor those who want to manage their own token length, you can explicitly
1137db96d56Sopenharmony_cispecify how much randomness is used for tokens by giving an :class:`int`
1147db96d56Sopenharmony_ciargument to the various ``token_*`` functions.  That argument is taken
1157db96d56Sopenharmony_cias the number of bytes of randomness to use.
1167db96d56Sopenharmony_ci
1177db96d56Sopenharmony_ciOtherwise, if no argument is provided, or if the argument is ``None``,
1187db96d56Sopenharmony_cithe ``token_*`` functions will use a reasonable default instead.
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci.. note::
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci   That default is subject to change at any time, including during
1237db96d56Sopenharmony_ci   maintenance releases.
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci
1267db96d56Sopenharmony_ciOther functions
1277db96d56Sopenharmony_ci---------------
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci.. function:: compare_digest(a, b)
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci   Return ``True`` if strings or
1327db96d56Sopenharmony_ci   :term:`bytes-like objects <bytes-like object>`
1337db96d56Sopenharmony_ci   *a* and *b* are equal, otherwise ``False``,
1347db96d56Sopenharmony_ci   using a "constant-time compare" to reduce the risk of
1357db96d56Sopenharmony_ci   `timing attacks <https://codahale.com/a-lesson-in-timing-attacks/>`_.
1367db96d56Sopenharmony_ci   See :func:`hmac.compare_digest` for additional details.
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ciRecipes and best practices
1407db96d56Sopenharmony_ci--------------------------
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ciThis section shows recipes and best practices for using :mod:`secrets`
1437db96d56Sopenharmony_cito manage a basic level of security.
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ciGenerate an eight-character alphanumeric password:
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci.. testcode::
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci   import string
1507db96d56Sopenharmony_ci   import secrets
1517db96d56Sopenharmony_ci   alphabet = string.ascii_letters + string.digits
1527db96d56Sopenharmony_ci   password = ''.join(secrets.choice(alphabet) for i in range(8))
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ci
1557db96d56Sopenharmony_ci.. note::
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci   Applications should not
1587db96d56Sopenharmony_ci   `store passwords in a recoverable format <https://cwe.mitre.org/data/definitions/257.html>`_,
1597db96d56Sopenharmony_ci   whether plain text or encrypted.  They should be salted and hashed
1607db96d56Sopenharmony_ci   using a cryptographically strong one-way (irreversible) hash function.
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ciGenerate a ten-character alphanumeric password with at least one
1647db96d56Sopenharmony_cilowercase character, at least one uppercase character, and at least
1657db96d56Sopenharmony_cithree digits:
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ci.. testcode::
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci   import string
1707db96d56Sopenharmony_ci   import secrets
1717db96d56Sopenharmony_ci   alphabet = string.ascii_letters + string.digits
1727db96d56Sopenharmony_ci   while True:
1737db96d56Sopenharmony_ci       password = ''.join(secrets.choice(alphabet) for i in range(10))
1747db96d56Sopenharmony_ci       if (any(c.islower() for c in password)
1757db96d56Sopenharmony_ci               and any(c.isupper() for c in password)
1767db96d56Sopenharmony_ci               and sum(c.isdigit() for c in password) >= 3):
1777db96d56Sopenharmony_ci           break
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci
1807db96d56Sopenharmony_ciGenerate an `XKCD-style passphrase <https://xkcd.com/936/>`_:
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci.. testcode::
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ci   import secrets
1857db96d56Sopenharmony_ci   # On standard Linux systems, use a convenient dictionary file.
1867db96d56Sopenharmony_ci   # Other platforms may need to provide their own word-list.
1877db96d56Sopenharmony_ci   with open('/usr/share/dict/words') as f:
1887db96d56Sopenharmony_ci       words = [word.strip() for word in f]
1897db96d56Sopenharmony_ci       password = ' '.join(secrets.choice(words) for i in range(4))
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ciGenerate a hard-to-guess temporary URL containing a security token
1937db96d56Sopenharmony_cisuitable for password recovery applications:
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci.. testcode::
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci   import secrets
1987db96d56Sopenharmony_ci   url = 'https://example.com/reset=' + secrets.token_urlsafe()
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci..
2037db96d56Sopenharmony_ci   # This modeline must appear within the last ten lines of the file.
2047db96d56Sopenharmony_ci   kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8;
205