• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
20The :mod:`secrets` module is used for generating cryptographically strong
21random numbers suitable for managing data such as passwords, account
22authentication, security tokens, and related secrets.
23
24In particularly, :mod:`secrets` should be used in preference to the
25default pseudo-random number generator in the :mod:`random` module, which
26is designed for modelling and simulation, not security or cryptography.
27
28.. seealso::
29
30   :pep:`506`
31
32
33Random numbers
34--------------
35
36The :mod:`secrets` module provides access to the most secure source of
37randomness 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
58Generating tokens
59-----------------
60
61The :mod:`secrets` module provides functions for generating secure
62tokens, suitable for applications such as password resets,
63hard-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
101How many bytes should tokens use?
102^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
103
104To be secure against
105`brute-force attacks <https://en.wikipedia.org/wiki/Brute-force_attack>`_,
106tokens need to have sufficient randomness.  Unfortunately, what is
107considered sufficient will necessarily increase as computers get more
108powerful and able to make more guesses in a shorter period.  As of 2015,
109it is believed that 32 bytes (256 bits) of randomness is sufficient for
110the typical use-case expected for the :mod:`secrets` module.
111
112For those who want to manage their own token length, you can explicitly
113specify how much randomness is used for tokens by giving an :class:`int`
114argument to the various ``token_*`` functions.  That argument is taken
115as the number of bytes of randomness to use.
116
117Otherwise, if no argument is provided, or if the argument is ``None``,
118the ``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
126Other 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 reduce the risk of
133   `timing attacks <https://codahale.com/a-lesson-in-timing-attacks/>`_.
134   See :func:`hmac.compare_digest` for additional details.
135
136
137Recipes and best practices
138--------------------------
139
140This section shows recipes and best practices for using :mod:`secrets`
141to manage a basic level of security.
142
143Generate 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 not
155   `store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_,
156   whether plain text or encrypted.  They should be salted and hashed
157   using a cryptographically-strong one-way (irreversible) hash function.
158
159
160Generate a ten-character alphanumeric password with at least one
161lowercase character, at least one uppercase character, and at least
162three digits:
163
164.. testcode::
165
166   import string
167   alphabet = string.ascii_letters + string.digits
168   while True:
169       password = ''.join(choice(alphabet) for i in range(10))
170       if (any(c.islower() for c in password)
171               and any(c.isupper() for c in password)
172               and sum(c.isdigit() for c in password) >= 3):
173           break
174
175
176Generate an `XKCD-style passphrase <https://xkcd.com/936/>`_:
177
178.. testcode::
179
180   # On standard Linux systems, use a convenient dictionary file.
181   # Other platforms may need to provide their own word-list.
182   with open('/usr/share/dict/words') as f:
183       words = [word.strip() for word in f]
184       password = ' '.join(choice(words) for i in range(4))
185
186
187Generate a hard-to-guess temporary URL containing a security token
188suitable for password recovery applications:
189
190.. testcode::
191
192   url = 'https://mydomain.com/reset=' + token_urlsafe()
193
194
195
196..
197   # This modeline must appear within the last ten lines of the file.
198   kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8;
199