secrets — Gera números aleatórios seguros para gerenciar segredos

Novo na versão 3.6.

Código-fonte: Lib/secrets.py


O módulo secrets é usado para gerar números aleatórios criptograficamente fortes, adequados para o gerenciamento de dados, como senhas, autenticação de conta, tokens de segurança e segredos relacionados.

Em particular, secrets deve ser usado em preferência ao gerador de números pseudoaleatórios padrão no módulo random, que é projetado para modelagem e simulação, não segurança ou criptografia.

Ver também

PEP 506

Números aleatórios

O módulo secrets fornece acesso à fonte mais segura de aleatoriedade que seu sistema operacional fornece.

class secrets.SystemRandom

Uma classe para gerar números aleatórios usando as fontes da mais alta qualidade fornecidas pelo sistema operacional. Veja random.SystemRandom para detalhes adicionais.

secrets.choice(sequence)

Retorna um elemento escolhido aleatoriamente de uma sequência não vazia.

secrets.randbelow(n)

Retorna um int aleatório no intervalo [0, n).

secrets.randbits(k)

Retorna um int com k bits aleatórios.

Gerando tokens

O módulo secrets fornece funções para gerar tokens seguros, adequados para aplicativos como redefinições de senha, URLs difíceis de adivinhar e semelhantes.

secrets.token_bytes([nbytes=None])

Retorna uma string de byte aleatória contendo nbytes número de bytes. Se nbytes for None ou não fornecido, um padrão razoável é usado.

>>> token_bytes(16)  
b'\xebr\x17D*t\xae\xd4\xe3S\xb6\xe2\xebP1\x8b'
secrets.token_hex([nbytes=None])

Retorna uma string de texto aleatória, em hexadecimal. A string tem nbytes bytes aleatórios, cada byte convertido em dois dígitos hexadecimais. Se nbytes for None ou não fornecido, um padrão razoável é usado.

>>> token_hex(16)  
'f9bf78b9a18ce6d46a0cd2b0b86df9da'
secrets.token_urlsafe([nbytes=None])

Retorna uma string de texto segura para URL aleatória, contendo nbytes bytes aleatórios. O texto é codificado em Base64, portanto, em média, cada byte resulta em aproximadamente 1,3 caracteres. Se nbytes for None ou não fornecido, um padrão razoável é usado.

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

Quantos bytes os tokens devem usar?

Para estar seguro contra ataques de força bruta, os tokens precisam ter aleatoriedade suficiente. Infelizmente, o que é considerado suficiente necessariamente aumentará à medida que os computadores ficarem mais poderosos e capazes de fazer mais suposições em um período mais curto. A partir de 2015, acredita-se que 32 bytes (256 bits) de aleatoriedade são suficientes para o caso de uso típico esperado para o módulo secrets.

Para aqueles que desejam gerenciar seu próprio comprimento de token, você pode especificar explicitamente quanta aleatoriedade é usada para tokens, fornecendo um argumento int para as várias funções token_*. Esse argumento é considerado o número de bytes de aleatoriedade a serem usados.

Caso contrário, se nenhum argumento for fornecido, ou se o argumento for None, as funções token_* usarão um padrão razoável.

Nota

Esse padrão está sujeito a alterações a qualquer momento, inclusive durante as versões de manutenção.

Outras funções

secrets.compare_digest(a, b)

Retorna True se as strings a e b forem iguais, caso contrário, False, de forma a reduzir o risco de ataques de temporização. Veja hmac.compare_digest() para detalhes adicionais.

Receitas e melhores práticas

Esta seção mostra as receitas e melhores práticas para usar secrets para gerenciar um nível básico de segurança.

Gerar uma senha alfanumérica de oito caracteres:

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

Nota

Os aplicativos não devem armazenar senhas em um formato recuperável, seja em texto simples ou criptografado. Elas devem ser salgadas e transformadas em hash usando uma função hash de sentido único criptograficamente forte (irreversível).

Gerar uma senha alfanumérica de dez caracteres com pelo menos um caractere minúsculo, pelo menos um caractere maiúsculo e pelo menos três 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

Gerar uma senha longa do 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))

Gerar uma URL temporária difícil de adivinhação contendo um token de segurança adequado para aplicativos de recuperação de senha:

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