pyauth / pyotp

Python One-Time Password Library
https://pyauth.github.io/pyotp/
Other
2.97k stars 323 forks source link

Update random_base32 Function for Cryptographic Security #168

Closed avri-schneider closed 3 months ago

avri-schneider commented 3 months ago

Description: The current implementation of the random_base32 function uses the random module to generate random base32 strings. However, the random module is not suitable for cryptographic purposes as it is not designed to be secure. The secrets module, introduced in Python 3.6, is specifically designed for generating cryptographically secure random numbers.

Current Implementation:

import random

def random_base32(length: int = 26, chars: Sequence[str] = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')) -> str:
    if length < 26:
        raise ValueError("Secrets should be at least 128 bits")

    return ''.join(
        random.choice(chars)
        for _ in range(length)
    )

Proposed Change: Replace the use of the random module with the secrets module to ensure the function is suitable for cryptographic applications.

Updated Implementation:

import secrets
from typing import Sequence

def random_base32(length: int = 26, chars: Sequence[str] = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')) -> str:
    if length < 26:
        raise ValueError("Secrets should be at least 128 bits")

    return ''.join(
        secrets.choice(chars)
        for _ in range(length)
    )

References:

  1. Python random module documentation

    • "Warning: The pseudo-random generators of this module should not be used for security purposes. Use secrets for cryptographic applications."
  2. Python secrets module documentation

    • "The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets."
  3. PEP 506 – Adding A Secrets Module To The Standard Library

    • "This PEP proposes the addition of a new module, secrets, to Python's standard library. This module will provide functions for securely generating random numbers, suitable for use in cryptographic applications."

Impact: Updating the function to use the secrets module will enhance the security of the generated base32 strings, making them suitable for use in cryptographic contexts such as generating secure tokens and passwords.

kislyuk commented 3 months ago

Thanks for your interest in PyOTP. Your idea of the current implementation is not correct, and PyOTP already uses the cryptographically strong system random number generator instead of the Mersenne Twister implementation that the warnings you cited refer to. Please take a look at https://github.com/pyauth/pyotp/blob/develop/src/pyotp/compat.py and https://github.com/pyauth/pyotp/blob/develop/src/pyotp/__init__.py#L7 to see how this is implemented.

avri-schneider commented 3 months ago

Thanks for this and sorry for opening this issue - I missed this 🙏