secrets Module¶
The secrets module provides cryptographically strong random number generation for security-sensitive applications like password generation and token creation.
Complexity Reference¶
| Operation | Time | Space | Notes |
|---|---|---|---|
token_bytes() |
O(n) | O(n) | n = number of bytes |
token_hex() |
O(n) | O(n) | n = number of bytes |
token_urlsafe() |
O(n) | O(n) | n = number of bytes |
choice() |
O(1) | O(1) | Cryptographically secure selection |
randbelow() |
O(1) | O(1) | Cryptographically secure random int |
Token Generation¶
Bytes and Hex Tokens¶
import secrets
# Generate random bytes - O(n)
token = secrets.token_bytes(32) # 32 random bytes
# Generate hex string - O(n)
hex_token = secrets.token_hex(16)
# Example: 'a3f7b2c9d1e4f8a5'
# Generate URL-safe token - O(n)
url_token = secrets.token_urlsafe(32)
# Example: 'pL_kZa7xX-vJmN5qR2sT_uV3wY6zA'
Common Token Uses¶
import secrets
# Session token - O(n)
session_id = secrets.token_urlsafe(32)
# Password reset link - O(n)
reset_token = secrets.token_hex(32)
# API key - O(n)
api_key = secrets.token_urlsafe(64)
# CSRF token - O(n)
csrf_token = secrets.token_hex(16)
Random Selection¶
Secure Choices¶
import secrets
# Choose from sequence - O(1)
characters = 'abcdefghijklmnopqrstuvwxyz0123456789'
password = ''.join(secrets.choice(characters) for _ in range(12))
# Random element - O(1)
choices = ['apple', 'banana', 'cherry']
selected = secrets.choice(choices)
Secure Integers¶
Random Number Generation¶
import secrets
# Random integer in range [0, k) - O(1)
random_int = secrets.randbelow(100)
# Inclusive range [a, b] - O(1)
def randint(a, b):
return a + secrets.randbelow(b - a + 1)
rolls = [randint(1, 6) for _ in range(3)] # 3 dice rolls
Password Generation¶
Strong Passwords¶
import secrets
import string
def generate_password(length=16):
# O(length)
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
password = ''.join(secrets.choice(alphabet) for _ in range(length))
return password
pwd = generate_password(16)
print(f"Generated: {pwd}")
Using Recipes¶
import secrets
import string
def generate_secure_password(length=12):
# Ensure mix of character types - O(length)
while True:
password = ''.join(
secrets.choice(string.ascii_letters + string.digits + string.punctuation)
for _ in range(length)
)
# Validate has upper, lower, digit, special
if (any(c.isupper() for c in password) and
any(c.islower() for c in password) and
any(c.isdigit() for c in password)):
return password
Common Patterns¶
Web Authentication¶
import secrets
# Generate tokens for authentication - O(n)
def create_session_token():
return secrets.token_urlsafe(32)
def create_password_reset_token():
return secrets.token_hex(32)
def create_email_verification_token():
return secrets.token_urlsafe(16)
# Store with expiration
session = {
'token': create_session_token(),
'user_id': 123,
'expires': datetime.now() + timedelta(hours=24)
}
Secure Lottery Selection¶
import secrets
def lottery_selection(participants, winners=5):
# O(1) per selection
selected = []
for _ in range(min(winners, len(participants))):
idx = secrets.randbelow(len(participants))
selected.append(participants.pop(idx))
return selected
participants = list(range(100))
lucky = lottery_selection(participants, 5)
Security Considerations¶
Best Practices¶
import secrets
# ✅ DO: Use secrets for security-sensitive data
password_reset_token = secrets.token_urlsafe()
# ✅ DO: Use sufficient length
token = secrets.token_hex(32) # 64 hex chars (256 bits)
# ❌ DON'T: Use random module for security
import random
insecure_token = random.randbytes(16) # Don't use!
# ❌ DON'T: Use insufficient entropy
short_token = secrets.token_hex(4) # Too short for security
Related Modules¶
- random Module - Non-cryptographic randomness
- hashlib Module - Secure hashing
- hmac Module - Message authentication codes
- ssl Module - SSL/TLS security