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
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)¶ Retorna un elemento aleatorio de una secuencia no vacía.
-
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)¶ Retorna
True
si las cadenas de caracteres a y b son iguales, de lo contrario,False
, de forma tal que se reduzca el riesgo de ataques de análisis temporal. Verhmac.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
Las aplicaciones no deben almacenar contraseñas en un formato recuperable, ya sea en texto plano o encriptado. Deberían ser saladas y hasheadas usando una función hash unidireccional (irreversible) y criptográficamente fuerte.
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()