Indice
Fundo
Python é amplamente usado para web scraping e APIs , lidar com bancos de dados, enviar e-mails e outras tarefas que podem envolver credenciais, como nome de usuário ou senha. Felizmente, existem várias maneiras de ocultar uma senha em um script Python, bem como armazenar várias senhas para muitos usuários, se necessário. Nesta postagem, falaremos sobre três desses pacotes – chaveiro , passlib e criptografia , com foco nos dois primeiros.
Como esconder uma senha em um script Python com chaveiro
O keyring é um pacote fácil de usar que permite armazenar uma senha no armazenamento de credenciais do sistema operacional. É ótimo porque pode funcionar em vários sistemas operacionais diferentes. Para começar, use o pip para instalar:
pip install keyring
A seguir, vamos importar o chaveiro .
import keyring
Depois de importar o chaveiro , podemos armazenar uma combinação de nome de usuário / senha usando o método set_password . Este método possui três parâmetros. Primeiro, é necessário um “servicename”. Este é o nome que escolhemos para qualquer serviço ao qual nosso nome de usuário / senha está associado, por exemplo, e-mail, banco de dados, etc. Em nosso exemplo, vamos chamá-lo apenas de “teste”. Em seguida, o segundo e o terceiro parâmetros são o nome de usuário e a senha, respectivamente.
keyring.set_password("test", "secret_username", "secret_password")
Para recuperar a senha, só precisamos usar o método get_password com o valor “servicename” e nome de usuário.
keyring.get_password("test", "secret_username")
Depois de definir a senha, ela permanece armazenada por nosso sistema operacional – portanto, se você iniciar uma nova sessão Python, poderá recuperá-la da mesma forma.
Vamos supor, por exemplo, que estejamos nos conectando a um banco de dados ( leia mais sobre isso aqui ), onde precisamos passar credenciais.
import pyodbc
channel = pyodbc.connect("DRIVER={SQLite3 ODBC Driver};SERVER=localhost;DATABASE=sample_database.db;Uid=secret_username;Pwd=secret_password;'")
Podemos alterar este código para usar o chaveiro :
import pyodbc
import keyring
channel = pyodbc.connect("DRIVER={SQLite3 ODBC Driver};SERVER=localhost;DATABASE=sample_database.db;Uid=secret_username;Pwd=" + keyring.get_password("test", "secret_username") + ";")
O chaveiro também pode ser útil ao programar um script Python em produção que requer uma senha ou credenciais.
Como fazer hash de senhas com passlib
Uma maneira alternativa de proteger as senhas em Python é o hash . Isso pode ser útil se você estiver lidando com o armazenamento de muitas senhas, como credenciais para um aplicativo da web (por exemplo, Flask ou Django ). O hash é diferente da criptografia porque a criptografia funciona como um método bidirecional. Qualquer senha criptografada pode ser descriptografada. O hash, por outro lado, funciona mapeando um valor (como uma senha) para um novo valor embaralhado. Idealmente, não deve haver uma maneira de mapear o valor / senha com hash de volta ao valor / senha original.
Vamos instalar passlib com pip.
pip install passlib
Configurando um objeto CryptContext
A seguir, vamos importar o CryptContext classe de passlib.context .
from passlib.context import CryptContext
A próxima etapa é configurar nosso objeto CryptContext . Primeiro, para fazer isso, precisamos decidir qual algoritmo de hash queremos usar. Existem várias possibilidades aqui, mas várias são especificamente recomendadas pela biblioteca passlib :argon2bcryptpbkdf2_sha256pbkdf2_sha512sha256_cryptsha512_crypt
Alguns desses algoritmos requerem a instalação de pacotes adicionais. Se você tentar usá-los sem essas dependências, receberá uma mensagem solicitando a instalação de alguns pacotes primeiro. Por exemplo, o pacote argon2_cffi é necessário para usar o algoritmo argon2 acima.
Em segundo lugar, também precisamos especificar o número de “rodadas”. Uma rodada é uma coleção de operações que formam uma função. Esta função é então executada várias vezes para mapear nossa senha para uma versão em hash. Um número menor de rodadas significará que tudo o que você está fazendo hash não é tão seguro porque menos operações estão sendo realizadas para embaralhar as informações. No entanto, um número maior de rodadas levará mais tempo para concluir a operação de hash. O número de rodadas a serem escolhidas também depende do algoritmo que você escolher. A escolha do número de rodadas para fins de segurança tem a ver principalmente com a lentidão, ou seja, se for rápido para gerar um hash, também é mais rápido descobrir o valor original por força bruta. Algoritmos como bcrypt e argon2 são mais lentos para produzir valores hash e, portanto, geralmente considerados mais seguros.
# create CryptContext object
context = CryptContext(
schemes=["pbkdf2_sha256"],
default="pbkdf2_sha256",
pbkdf2_sha256__default_rounds=50000
)
# hash password
context.hash("test_password")
Neste primeiro exemplo, estamos usando o algoritmo PBKDF2-SHA256, pois essa é uma escolha comum e normalmente funciona sem problemas em diferentes sistemas operacionais. Uma vez que o objeto CryptContext é criado, podemos hash nossa senha usando o método hash como acima.
Como verificar se uma senha com hash está correta
Para verificar se uma senha corresponde ao hash correspondente, podemos usar o método de verificação . O método de verificação não “descompõe” a senha com hash, mas, em vez disso, faz o hash da senha desprotegida e a compara com a versão com hash.
hashed_password = context.hash("test_password")
context.verify("test_password", hashed_password)
A seguir, vejamos outro exemplo. Desta vez, usaremos o algoritmo argon2. Como mencionado acima, precisamos primeiro instalar o pacote argon2_cffi para isso. argon2 é um algoritmo relativamente mais recente que foi projetado especificamente para hash de senhas.
pip install argon2_cffi
Agora, podemos criar nosso objeto CryptContext .
# create CryptContext object
context = CryptContext(
schemes=["argon2"],
default="argon2",
argon2__default_rounds=1000
)
# hash password
context.hash("test_password")
O pacote de criptografia
Por fim, vamos falar sobre o pacote de criptografia . Podemos instalar este pacote usando pip:
pip install cryptography
A seguir, vamos importar a classe Fernet da criptografia . Isso nos permitirá gerar uma chave, que podemos usar para criptografar nossa senha. Nota: este processo está executando criptografia , não hash. Conforme mencionado acima, o hash é recomendado porque geralmente é mais seguro, mas a criptografia é um pouco melhor do que armazenar senhas em texto simples.
# import the Fernet class
from cryptography.fernet import Fernet
# generate key
key = Fernet.generate_key()
Em seguida, podemos usar nossa chave para criptografar nossa senha usando o método de criptografia . Observe que a senha deve ser passada em bytes, como abaixo.
enc = f.encrypt(b"test_password")
Por último, podemos decriptografar a senha criptografada usando o método de decriptografia .
f.decrypt(enc)
Conclusão
Isso é tudo por este post! Neste artigo, abordamos como ocultar uma senha em um script Python usando o chaveiro , como fazer hash de senhas usando passlib e a diferença entre hash e criptografia.