# `secrets` — Genera números aleatorios seguros para trabajar con secretos criptográficos

Nuevo en la versión 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`(sequence)

  Return a randomly chosen element from a non-empty sequence.

`secrets.``randbelow`(n)

  Retorna un entero aleatorio en el rango [0, n).

`secrets.``randbits`(k)

  Retorna un entero con k bits aleatorios.

## 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])

  Retorna una cadena de bytes aleatorios que contiene nbytes número de bytes. Si nbytes es `None` o no se suministra, se utiliza un valor por defecto razonable.

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

`secrets.``token_hex`([nbytes=None])

  Retorna una cadena de caracteres aleatoria, en hexadecimal. La cadena de caracteres tiene nbytes bytes aleatorios, cada byte convertido a dos dígitos hexadecimales. Si nbytes es `None` o no se suministra, se utiliza un valor por defecto razonable.

      >>> token_hex(16)
      'f9bf78b9a18ce6d46a0cd2b0b86df9da'

`secrets.``token_urlsafe`([nbytes=None])

  Retorna una cadena de caracteres aleatoria para usarse en URLs, que contiene nbytes bytes aleatorios. El texto está codificado en Base64, por lo que en promedio cada byte resulta en aproximadamente 1,3 caracteres. Si nbytes es `None` o no se suministra, se utiliza un valor por defecto razonable.

      >>> 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.

En caso contrario, si no se proporciona ningún argumento, o si el argumento es `None`, las funciones `token_*` utilizarán en su lugar un valor por defecto razonable.

Nota

El valor por defecto está sujeto a cambios en cualquier momento, incluso en los lanzamientos de mantenimiento.

## Otras funciones

`secrets.``compare_digest`(a, b)

  Return `True` if strings a and b are equal, otherwise `False`, using a «constant-time compare» to reduce the risk of timing attacks. See `hmac.compare_digest()` for additional details.

## 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()