blob: bc4766da2785b36dfe8b0621abb5389d3138f197 [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
Sanyam Khurana1b4587a2017-12-06 22:09:33 +0530133 `timing attacks <https://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
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200148 import secrets
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000149 alphabet = string.ascii_letters + string.digits
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200150 password = ''.join(secrets.choice(alphabet) for i in range(8))
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000151
152
153.. note::
154
Steven D'Aprano151f5d52016-04-17 13:05:10 +1000155 Applications should not
156 `store passwords in a recoverable format <http://cwe.mitre.org/data/definitions/257.html>`_,
157 whether plain text or encrypted. They should be salted and hashed
158 using a cryptographically-strong one-way (irreversible) hash function.
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000159
160
161Generate a ten-character alphanumeric password with at least one
162lowercase character, at least one uppercase character, and at least
163three digits:
164
165.. testcode::
166
167 import string
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200168 import secrets
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000169 alphabet = string.ascii_letters + string.digits
170 while True:
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200171 password = ''.join(secrets.choice(alphabet) for i in range(10))
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000172 if (any(c.islower() for c in password)
173 and any(c.isupper() for c in password)
174 and sum(c.isdigit() for c in password) >= 3):
175 break
176
177
Sanyam Khurana1b4587a2017-12-06 22:09:33 +0530178Generate an `XKCD-style passphrase <https://xkcd.com/936/>`_:
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000179
180.. testcode::
181
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200182 import secrets
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000183 # On standard Linux systems, use a convenient dictionary file.
184 # Other platforms may need to provide their own word-list.
185 with open('/usr/share/dict/words') as f:
186 words = [word.strip() for word in f]
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200187 password = ' '.join(secrets.choice(words) for i in range(4))
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000188
189
190Generate a hard-to-guess temporary URL containing a security token
191suitable for password recovery applications:
192
193.. testcode::
194
Daniel Chimenocf8abcb2018-05-19 17:01:49 +0200195 import secrets
196 url = 'https://mydomain.com/reset=' + secrets.token_urlsafe()
Steven D'Apranob2871fa2016-04-17 01:42:33 +1000197
198
199
200..
201 # This modeline must appear within the last ten lines of the file.
202 kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8;