Python 3.6 introduced a secrets module for generating robust and secure random numbers. In this lesson, you’ll learn how to use secrets.SystemRandom() class and secrets module functions to create random numbers, data, URLs, and tokens securely and safely.
Table of contents
Why use the secrets module
The cryptographically secure random generator generates random data using synchronization methods to ensure that no two processes can obtain the same data simultaneously.

The random generator provided by the Python random module is a pseudo-random number generator that is not cryptographically secure. As a result secrets module is added in Python 3.6 and onwards to secure the random number generator.
Before Python 3.6, we have the random() and SystemRandom class to cryptographically secure random generator.
The secrets module is CSPRNG, i.e., cryptographically strong Pseudo-Random Number Generator. It is used to produce random numbers that are secure and useful in security-sensitive applications. The PEP – 0506 is designed to add the secrets module to the Python standard library.
Use the secrets module for following standard security-related functions.
- Generating random numbers,
- Creating passwords and OTP.
- Random token.
- Password recovery safe URLs and session keys.
Note: The secrets module available only in Python 3.6 and above. If you are using an older version of Python, please refer to How to secure a random generator in Python.
The secrets module is based on os.urandom() and random.SystemRandom(), an the interface to the operating system’s best source of cryptographic randomness.
- On windows,
os.urandom()internally uses CryptGenRandom(). - Linux 3.17 and newer, the
getrandom()syscall used when available. - On OpenBSD 5.6 and newer, the C
getentropy()function is used.
Let see how to use the secrets module.
Class secrets.SystemRandom
- A class for generating secure random numbers using the highest-quality sources provided by the operating system.
- Using the
secrets.SystemRandomclass, we can use all the functions of a random module. - Before the secrets module, we were using
random.SystemRandomclass to cryptographically secure random data. The same class is also accessible using the secrets module. Just execute thesecrets.SystemRandom(), and it will return the instance of a secure random generator
Let see the example of how to use secrets.SystemRandom class to secure the random generator.
Secrets Module Functions
Let see how to use secrets module functions.
| Function | Description |
|---|---|
secrets.SystemRandom() | Get an instance of the secure random generator |
secrets.randbelow(n) | Generate a secure random integer number |
secrets.choice(seq) | Returns a secure random element from a non-empty sequence |
secrets.randbits(k) | returns a secure unsigned integer with k random bits |
secrets.token_bytes([nbytes=None]) | Return a secure random byte string |
secrets.token_hex([nbytes=None]) | Return a secure random text string, in hexadecimal format |
secrets.token_urlsafe([nbytes=None]) | Return a secure random URL-safe text string |
secrets.compare_digest(a, b) | To reduce the risk of timing attacks |
randbelow(n)
- Use the
secrets.randbelowfunction to generate a secure integer number. - This function returns a secure random integer in the range [0, n). Here
nis the exclusive upper bound. - 0 is the starting number in the range, and
nis the last number. - For example,
secrets.randbelow(10)generate a single random number from 0 to 9.
Example:
choice(sequence)
The secrets.choice(sequence) method returns a secure randomly-chosen element from a non-empty sequence. Here sequence can be list, tuple, or string.
Example:
randbits(k)
- This method returns a secure unsigned integer with
krandom bits. - This function is to generate a random bitmask that would contain
Nbits set (this is not the same as generating a random integer since that is not guaranteed to haveNbits set in it). - A random number generated using
randbitsis more secure.
It generates a random integer within a bit range.
- If
k=4then Unsigned integer From 0 to 15. k=8then Unsigned integer From 0 to 255.- If
k=16then Unsigned integer From 0 to 65,535, and so on.
Let’s see the example :
Generate secure token using secrets module
The secrets module provides functions for generating the secure tokens, useful for applications to generate reset password tokens and hard-to-guess URLs.
Use the following functions to generate a secure token.
secrets.token_bytes([nbytes=None]): Return a secure random byte string containing the number of bytes. Ifn-bytesare not supplied, a reasonable default gets used.secrets.token_hex([nbytes=None]): Return a secure random text string in hexadecimal format. The string hasn-bytesrandom bytes, and each byte is converted to two hex digits. If n-bytes are not supplied, a reasonable default gets used.secrets.token_urlsafe([nbytes=None]): Return a secure random URL-safe text string, containing n-bytes random bytes. Use this method to generate secure hard-to-guess URLs.
Example to generate secure tokens
Output:
b'&\x19H\xc0r{\xa5\xd6\x0b\xf5\xb2\x1d\xc6\xf6]0'
dd772eb0c11c4995c3c9db5a20a555c31d70547c30df31e818be7c7832bb44f1
demo.com/customer/eric/reset=GzWfp5xCcuFsnEUb9qqN_v94_XOx9hPwSGszdx4rNBk
How many bytes tokens should use
Tokens need to have sufficient randomness To secure against brute-force attacks and timing attacks. As per experts, 32 bytes (256 bits) of randomness is enough to secure against brute-force attacks. You should choose byte size as per your requirement.
Reduce timing attack using compare_digest(a, b)
To reduce the risk of timing attacks secrets module has the compare_digest(a, b) function. This function returns True if string a and b are equal, otherwise False to reduce the risk of timing attacks.
Practical Example of secrets module
Let see the example now. In this example, we generate a temporary password and send this password on a temporary hard-to-guess URL so the client can reset his password using this URL.
Steps: –
- Generate a ten-character alphanumeric password with at least one lowercase character, at least one uppercase character, at least one digits, and one special symbol.
- Generate a temporary URL
Example:
Next Steps
To practice what you learned in this article, I have created a Python random data generation Exercise and Python random data generation Quiz to test your random data generation concepts.
References:

Does this module support specifying a random seed?
I found this article so intresting thanks…
You’re welcome, Fansheri.
How do we quantify how secure the passwords generated by secrets module are?
Hey Rishabh Gupta, secrets module used to produce random-looking numbers which are resistant to prediction. Please have a look at PEP 506: Adding A Secrets Module To The Standard Library for more clarity.
Hi Vishal
I liked your tutorials. Can you create tutorials on how to parse XML file using element tree and storing data in dict format using xmltodict.
I will let you know
There is an error in your randbelow() example. randbelow(10) will generate ints in the inclusive range 0 to 9, NOT 0 to 10 inclusive as the example suggests.
Thanks for noticing. I have corrected a description.
Thanks for the article. I didn’t know anything about this built-in. Will take advantage of it.
I am glad you liked it