# `secrets` — Generate secure random numbers for managing secrets

Added in version 3.6.

Código fuente: Lib/secrets.py

El módulo `secrets` se usa para generar números aleatorios criptográficamente fuertes, apropiados para trabajar con datos como contraseñas, autenticación de cuentas, tokens de seguridad y secretos relacionados.

En particular, `secrets` se debe usar en lugar del generador de números pseudoaleatorios del módulo `random`, que está diseñado para el modelado y la simulación, no para la seguridad o la criptografía.

Ver también

PEP 506

## Números aleatorios

El módulo `secrets` provee acceso a la fuente más segura de aleatoriedad que proporciona su sistema operativo.

class secrets.SystemRandom

  Una clase para generar números aleatorios utilizando las fuentes de mayor calidad que proporciona el sistema operativo. Ver `random.SystemRandom` para más detalles.

secrets.choice(seq)

  Retorna un elemento elegido aleatoriamente a partir de una secuencia no vacía.

secrets.randbelow(exclusive_upper_bound)

  Return a random int in the range [0, exclusive_upper_bound).

secrets.randbits(k)

  Return a non-negative int with k random bits.

## Generando tokens

El módulo `secrets` provee funciones para generar tokens seguros, adecuados para aplicaciones como el restablecimiento de contraseñas, URLs difíciles de adivinar, y similares.

secrets.token_bytes(nbytes=None)

  Return a random byte string containing nbytes number of bytes.

  If nbytes is not specified or `None`, `DEFAULT_ENTROPY` is used instead.

      >>> token_bytes(16)
      b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'

secrets.token_hex(nbytes=None)

  Return a random text string, in hexadecimal. The string has nbytes random bytes, each byte converted to two hex digits.

  If nbytes is not specified or `None`, `DEFAULT_ENTROPY` is used instead.

      >>> token_hex(16)
      'f9bf78b9a18ce6d46a0cd2b0b86df9da'

secrets.token_urlsafe(nbytes=None)

  Return a random URL-safe text string, containing nbytes random bytes. The text is Base64 encoded, so on average each byte results in approximately 1.3 characters.

  If nbytes is not specified or `None`, `DEFAULT_ENTROPY` is used instead.

      >>> token_urlsafe(16)
      'Drmhze6EPcv0fN_81Bj-nA'

### ¿Cuántos bytes deben tener los tokens?

Para estar seguros contra los ataques de fuerza bruta, los tokens deben tener suficiente aleatoriedad. Desafortunadamente, lo que es considerado suficiente necesariamente aumentará a medida que las computadoras se vuelvan más potentes y capaces de hacer más pruebas en un período más corto. Desde 2015 se cree que 32 bytes (256 bits) de aleatoriedad son considerados suficientes para el típico caso de uso del módulo `secrets`.

Para quienes quieran gestionar la longitud de sus propios tokens, pueden especificar explícitamente cuánta aleatoriedad se utiliza para los tokens dando un argumento `int` a las funciones `token_*`. Ese argumento se toma como el número de bytes de aleatoriedad a utilizar.

Otherwise, if no argument is provided, or if the argument is `None`, the `token_*` functions uses `DEFAULT_ENTROPY` instead.

secrets.DEFAULT_ENTROPY

  Default number of bytes of randomness used by the `token_*` functions.

  The exact value is subject to change at any time, including during maintenance releases.

## Otras funciones

secrets.compare_digest(a, b)

  Retorna `True` si las cadenas de caracteres o objetos tipo-bytes a y b son iguales, de lo contrario `False`, usando una «comparación de tiempo constante» para reducir el riesgo de ataques de análisis temporal. Ver `hmac.compare_digest`()` para detalles adicionales.

## Recetas y mejores prácticas

Esta sección muestra las recetas y las mejores prácticas para usar `secrets` para conseguir un nivel mínimo de seguridad.

Generar una contraseña alfanumérica de ocho caracteres:

    import string
    import secrets
    alphabet = string.ascii_letters + string.digits
    password = ''.join(secrets.choice(alphabet) for i in range(8))

Nota

Applications should not store passwords in a recoverable format, whether plain text or encrypted. They should be salted and hashed using a cryptographically strong one-way (irreversible) hash function.

Generar una contraseña alfanumérica de diez caracteres con al menos un carácter en minúscula, al menos un carácter en mayúscula y al menos tres dígitos:

    import string
    import secrets
    alphabet = string.ascii_letters + string.digits
    while True:
        password = ''.join(secrets.choice(alphabet) for i in range(10))
        if (any(c.islower() for c in password)
                and any(c.isupper() for c in password)
                and sum(c.isdigit() for c in password) >= 3):
            break

Generar una contraseña al estilo XKCD:

    import secrets
    # On standard Linux systems, use a convenient dictionary file.
    # Other platforms may need to provide their own word-list.
    with open('/usr/share/dict/words') as f:
        words = [word.strip() for word in f]
        password = ' '.join(secrets.choice(words) for i in range(4))

Generar una URL temporal difícil de adivinar que contenga un token de seguridad adecuado para la recuperación de contraseñas:

    import secrets
    url = 'https://example.com/reset=' + secrets.token_urlsafe()