blob: 9bf848f9114359979e0af025400645f8a038184d [file] [log] [blame]
Steven D'Apranob2871fa2016-04-17 01:42:33 +10001: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
Steven D'Aprano151f5d52016-04-17 13:05:10 +100091 bytes. The text is Base64 encoded, so on average each byte results
Steven D'Apranob2871fa2016-04-17 01:42:33 +100092 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,
Steven D'Aprano151f5d52016-04-17 13:05:10 +1000109it is believed that 32 bytes (256 bits) of randomness is sufficient for
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000110the 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``,
Steven D'Aprano151f5d52016-04-17 13:05:10 +1000132 in such a way as to reduce the risk of
133 `timing attacks <http://codahale.com/a-lesson-in-timing-attacks/>`_.
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000134 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
Steven D'Aprano151f5d52016-04-17 13:05:10 +1000154 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.
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000158
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
Steven D'Aprano151f5d52016-04-17 13:05:10 +1000176Generate an `XKCD-style passphrase <http://xkcd.com/936/>`_:
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000177
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;