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