|
| 1 | +:mod:`secrets` --- Generate secure random numbers for managing secrets |
| 2 | +====================================================================== |
| 3 | + |
| 4 | +.. module:: secrets |
| 5 | + :synopsis: Generate secure random numbers for managing secrets. |
| 6 | + |
| 7 | +.. moduleauthor:: Steven D'Aprano <steve+python@pearwood.info> |
| 8 | +.. sectionauthor:: Steven D'Aprano <steve+python@pearwood.info> |
| 9 | +.. versionadded:: 3.6 |
| 10 | + |
| 11 | +.. testsetup:: |
| 12 | + |
| 13 | + from secrets import * |
| 14 | + __name__ = '<doctest>' |
| 15 | + |
| 16 | +**Source code:** :source:`Lib/secrets.py` |
| 17 | + |
| 18 | +------------- |
| 19 | + |
| 20 | +The :mod:`secrets` module is used for generating cryptographically strong |
| 21 | +random numbers suitable for managing data such as passwords, account |
| 22 | +authentication, security tokens, and related secrets. |
| 23 | + |
| 24 | +In particularly, :mod:`secrets` should be used in preference to the |
| 25 | +default pseudo-random number generator in the :mod:`random` module, which |
| 26 | +is designed for modelling and simulation, not security or cryptography. |
| 27 | + |
| 28 | +.. seealso:: |
| 29 | + |
| 30 | + :pep:`506` |
| 31 | + |
| 32 | + |
| 33 | +Random numbers |
| 34 | +-------------- |
| 35 | + |
| 36 | +The :mod:`secrets` module provides access to the most secure source of |
| 37 | +randomness that your operating system provides. |
| 38 | + |
| 39 | +.. class:: SystemRandom |
| 40 | + |
| 41 | + A class for generating random numbers using the highest-quality |
| 42 | + sources provided by the operating system. See |
| 43 | + :class:`random.SystemRandom` for additional details. |
| 44 | + |
| 45 | +.. function:: choice(sequence) |
| 46 | + |
| 47 | + Return a randomly-chosen element from a non-empty sequence. |
| 48 | + |
| 49 | +.. function:: randbelow(n) |
| 50 | + |
| 51 | + Return a random int in the range [0, *n*). |
| 52 | + |
| 53 | +.. function:: randbits(k) |
| 54 | + |
| 55 | + Return an int with *k* random bits. |
| 56 | + |
| 57 | + |
| 58 | +Generating tokens |
| 59 | +----------------- |
| 60 | + |
| 61 | +The :mod:`secrets` module provides functions for generating secure |
| 62 | +tokens, suitable for applications such as password resets, |
| 63 | +hard-to-guess URLs, and similar. |
| 64 | + |
| 65 | +.. function:: token_bytes([nbytes=None]) |
| 66 | + |
| 67 | + Return a random byte string containing *nbytes* number of bytes. |
| 68 | + If *nbytes* is ``None`` or not supplied, a reasonable default is |
| 69 | + used. |
| 70 | + |
| 71 | + .. doctest:: |
| 72 | + |
| 73 | + >>> token_bytes(16) #doctest:+SKIP |
| 74 | + b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b' |
| 75 | + |
| 76 | + |
| 77 | +.. function:: token_hex([nbytes=None]) |
| 78 | + |
| 79 | + Return a random text string, in hexadecimal. The string has *nbytes* |
| 80 | + random bytes, each byte converted to two hex digits. If *nbytes* is |
| 81 | + ``None`` or not supplied, a reasonable default is used. |
| 82 | + |
| 83 | + .. doctest:: |
| 84 | + |
| 85 | + >>> token_hex(16) #doctest:+SKIP |
| 86 | + 'f9bf78b9a18ce6d46a0cd2b0b86df9da' |
| 87 | + |
| 88 | +.. function:: token_urlsafe([nbytes=None]) |
| 89 | + |
| 90 | + Return a random URL-safe text string, containing *nbytes* random |
| 91 | + bytes. The text is Base64 encoded, so on average, each byte results |
| 92 | + in approximately 1.3 characters. If *nbytes* is ``None`` or not |
| 93 | + supplied, a reasonable default is used. |
| 94 | + |
| 95 | + .. doctest:: |
| 96 | + |
| 97 | + >>> token_urlsafe(16) #doctest:+SKIP |
| 98 | + 'Drmhze6EPcv0fN_81Bj-nA' |
| 99 | + |
| 100 | + |
| 101 | +How many bytes should tokens use? |
| 102 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 103 | + |
| 104 | +To be secure against |
| 105 | +`brute-force attacks <https://en.wikipedia.org/wiki/Brute-force_attack>`_, |
| 106 | +tokens need to have sufficient randomness. Unfortunately, what is |
| 107 | +considered sufficient will necessarily increase as computers get more |
| 108 | +powerful and able to make more guesses in a shorter period. As of 2015, |
| 109 | +it is believed that 64 bytes (512 bits) of randomness is sufficient for |
| 110 | +the typical use-case expected for the :mod:`secrets` module. |
| 111 | + |
| 112 | +For those who want to manage their own token length, you can explicitly |
| 113 | +specify how much randomness is used for tokens by giving an :class:`int` |
| 114 | +argument to the various ``token_*`` functions. That argument is taken |
| 115 | +as the number of bytes of randomness to use. |
| 116 | + |
| 117 | +Otherwise, if no argument is provided, or if the argument is ``None``, |
| 118 | +the ``token_*`` functions will use a reasonable default instead. |
| 119 | + |
| 120 | +.. note:: |
| 121 | + |
| 122 | + That default is subject to change at any time, including during |
| 123 | + maintenance releases. |
| 124 | + |
| 125 | + |
| 126 | +Other functions |
| 127 | +--------------- |
| 128 | + |
| 129 | +.. function:: compare_digest(a, b) |
| 130 | + |
| 131 | + Return ``True`` if strings *a* and *b* are equal, otherwise ``False``, |
| 132 | + in such a way as to redice the risk of |
| 133 | + `timing attacks <http://codahale.com/a-lesson-in-timing-attacks/>`_ . |
| 134 | + See :func:`hmac.compare_digest` for additional details. |
| 135 | + |
| 136 | + |
| 137 | +Recipes and best practices |
| 138 | +-------------------------- |
| 139 | + |
| 140 | +This section shows recipes and best practices for using :mod:`secrets` |
| 141 | +to manage a basic level of security. |
| 142 | + |
| 143 | +Generate an eight-character alphanumeric password: |
| 144 | + |
| 145 | +.. testcode:: |
| 146 | + |
| 147 | + import string |
| 148 | + alphabet = string.ascii_letters + string.digits |
| 149 | + password = ''.join(choice(alphabet) for i in range(8)) |
| 150 | + |
| 151 | + |
| 152 | +.. note:: |
| 153 | + |
| 154 | + Applications should |
| 155 | + `not store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_ , |
| 156 | + whether plain text or encrypted. They should always be salted and |
| 157 | + hashed using a cryptographically-strong one-way (irreversible) hash |
| 158 | + function. |
| 159 | + |
| 160 | + |
| 161 | +Generate a ten-character alphanumeric password with at least one |
| 162 | +lowercase character, at least one uppercase character, and at least |
| 163 | +three digits: |
| 164 | + |
| 165 | +.. testcode:: |
| 166 | + |
| 167 | + import string |
| 168 | + alphabet = string.ascii_letters + string.digits |
| 169 | + while True: |
| 170 | + password = ''.join(choice(alphabet) for i in range(10)) |
| 171 | + if (any(c.islower() for c in password) |
| 172 | + and any(c.isupper() for c in password) |
| 173 | + and sum(c.isdigit() for c in password) >= 3): |
| 174 | + break |
| 175 | + |
| 176 | + |
| 177 | +Generate an `XKCD-style passphrase <http://xkcd.com/936/>`_ : |
| 178 | + |
| 179 | +.. testcode:: |
| 180 | + |
| 181 | + # On standard Linux systems, use a convenient dictionary file. |
| 182 | + # Other platforms may need to provide their own word-list. |
| 183 | + with open('/usr/share/dict/words') as f: |
| 184 | + words = [word.strip() for word in f] |
| 185 | + password = ' '.join(choice(words) for i in range(4)) |
| 186 | + |
| 187 | + |
| 188 | +Generate a hard-to-guess temporary URL containing a security token |
| 189 | +suitable for password recovery applications: |
| 190 | + |
| 191 | +.. testcode:: |
| 192 | + |
| 193 | + url = 'https://mydomain.com/reset=' + token_urlsafe() |
| 194 | + |
| 195 | + |
| 196 | + |
| 197 | +.. |
| 198 | + # This modeline must appear within the last ten lines of the file. |
| 199 | + kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8; |
0 commit comments