PYnative

Python Programming

  • Learn Python
  • Exercises
  • Quizzes
  • Code Editor
  • Tricks
Home » Python » Random » Python Secrets Module to Generate secure random numbers for managing secrets

Python Secrets Module to Generate secure random numbers for managing secrets

Updated on: March 9, 2021 | Python Tags: Python Random

TweetF  sharein  shareP  Pin

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.

FunctionDescription
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
Secrets module functions

Also, see: –

  • Python random data generation Exercise
  • Python random data generation Quiz

Table of contents

  • Why use the secrets module
  • Class secrets.SystemRandom
  • Secrets Module Functions
    • randbelow(n)
    • choice(sequence)
    • randbits(k)
  • Generate secure token using secrets module
    • Example to generate secure tokens
    • How many bytes tokens should use
  • Practical Example of secrets module
  • Next Steps

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.

python secrets functions
python secrets functions

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.SystemRandom class, we can use all the functions of a random module.
  • Before the secrets module, we were using random.SystemRandom class to cryptographically secure random data. The same class is also accessible using the secrets module. Just execute the secrets.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.

import secrets

# Getting systemRandom class instance out of secrets module
secretsGenerator = secrets.SystemRandom()

# secure random integer numbers
random_number = secretsGenerator.randint(0, 50)
print(random_number)
# Output 38

# secure random integer number within given
random_number2 = secretsGenerator.randrange(4, 40, 4)
print(random_number2)
# Output 32

# Secure Random choice using secrets
number_list = [6, 12, 18, 24, 30, 36, 42, 48, 54, 60]
secure_choice = secretsGenerator.choice(number_list)
print(secure_choice)
# Output 60

# Secure Random sample
secure_sample = secretsGenerator.sample(number_list, 3)
print(secure_sample)
# output [12, 42, 48]

# Secure Random float number
secure_float = secretsGenerator.uniform(2.5, 25.5)
print(secure_float)
# Output 18.062235454990407

Secrets Module Functions

Let see how to use secrets module functions.

randbelow(n)

  • Use the secrets.randbelow function to generate a secure integer number.
  • This function returns a secure random integer in the range [0, n).  Here n is the exclusive upper bound.
  • 0 is the starting number in the range, and n is the last number.
  • For example, secrets.randbelow(10) generate a single random number from 0 to 9.

Example:

import secrets

# secure Random integer number
for i in range(3):
    print(secrets.randbelow(10), end=', ')
# Output 0, 8, 6,

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:

import secrets

name = "GuidoVanRossum"
# secrets choice from string is
print(secrets.choice(name))
# Output 'm'

name_list = ["Guido Van Rossum", "Bjarne Stroustrup", "Dennis Ritchie"]
# secure choice from list
print(secrets.choice(name_list))
# Output 'Bjarne Stroustrup'

randbits(k)

  • This method returns a secure unsigned integer with k random bits.
  • This function is to generate a random bitmask that would contain N bits set (this is not the same as generating a random integer since that is not guaranteed to have N bits set in it).
  • A random number generated using randbits is more secure.

It generates a random integer within a bit range.

  • If k=4 then Unsigned integer From 0 to 15.
  • k=8 then Unsigned integer From 0 to 255.
  • If k=16 then Unsigned integer From 0 to 65,535, and so on.

Let’s see the example :

import secrets

# using 4 bits
print(secrets.randbits(4))
# output 7

# using 8 bits
print(secrets.randbits(8))
# output 73

# using 16 bits
print(secrets.randbits(16))
# Output 509

# using 32 bits
print(secrets.randbits(32))
# Output 2740049514

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. If n-bytes are not supplied, a reasonable default gets used.
  • secrets.token_hex([nbytes=None]): Return a secure random text string in hexadecimal format. The string has n-bytes random 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

import secrets

# secure byte token
print(secrets.token_bytes(16))

# secure hexadecimal token
print(secrets.token_hex(32))

# generate secure URLs
passwordResetLink = "demo.com/customer/eric/reset="
passwordResetLink += secrets.token_urlsafe(32)
print(passwordResetLink)

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:

import secrets
import string

stringSource = string.ascii_letters + string.digits + string.punctuation
password = secrets.choice(string.ascii_lowercase)
password += secrets.choice(string.ascii_uppercase)
password += secrets.choice(string.digits)
password += secrets.choice(string.punctuation)

for i in range(6):
    password += secrets.choice(stringSource)

char_list = list(password)
secrets.SystemRandom().shuffle(char_list)
password = ''.join(char_list)
print("Secure Password is ", password)
# Output ^Kk58nL\(A

print("Ppassword Reset URL Link")
SecureURL = "https://demo.com/user/jhon/reset="
SecureURL += secrets.token_urlsafe(32)
print(SecureURL)
# https://demo.com/user/jhon/reset=Td3pRv_USCHfxQsBF0SFejEEFPp1NLaHBkbzth5gRjQ

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:

  • Secrets module official documentation
  • PEP 506: Adding a Secrets module to the standard library

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

Founder of PYnative.com I am a Python developer and I love to write articles to help developers. Follow me on Twitter. All the best for your future Python endeavors!

Related Tutorial Topics:

Python Random

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 10 questions
  • Each Quiz contains 12-15 MCQ
Exercises
Quizzes

Leave a Reply Cancel reply

your email address will NOT be published. all comments are moderated according to our comment policy.

Use <pre> tag for posting code. E.g. <pre> Your code </pre>

10 Comments

Working with random data

  • Guide to Generate Random Data
  • Random randint() & randrange()
  • Random Choice
  • Random Sample
  • Weighted random choices
  • Random Seed
  • Random Shuffle
  • Get Random Float Numbers
  • Generate Random String
  • Generate Secure random data
  • Secrets to Secure random data
  • Random Data Generation Exercise
  • Random Data Generation Quiz

All Python Topics

Python Basics Python Exercises Python Quizzes Python Regex Python Random Python Pandas Python Databases Python MySQL Python PostgreSQL Python SQLite Python JSON
TweetF  sharein  shareP  Pin

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Legal Stuff

  • About Us
  • Privacy Policy
  • Cookie Policy
  • Terms Of Use
  • Contact Us
DMCA.com Protection Status

Copyright © 2018-2021 · [pynative.com]

This website uses cookies to ensure you get the best experience on our website.Privacy PolicyGot it!