A partir do Python 3.4, o hashlib
módulo na biblioteca padrão contém funções de derivação chave que são "projetadas para hashing de senha seguro" .
Portanto, use um desses, como hashlib.pbkdf2_hmac
, com um sal gerado usando os.urandom
:
from typing import Tuple
import os
import hashlib
import hmac
def hash_new_password(password: str) -> Tuple[bytes, bytes]:
"""
Hash the provided password with a randomly-generated salt and return the
salt and hash to store in the database.
"""
salt = os.urandom(16)
pw_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
return salt, pw_hash
def is_correct_password(salt: bytes, pw_hash: bytes, password: str) -> bool:
"""
Given a previously-stored salt and hash, and a password provided by a user
trying to log in, check whether the password is correct.
"""
return hmac.compare_digest(
pw_hash,
hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
)
salt, pw_hash = hash_new_password('correct horse battery staple')
assert is_correct_password(salt, pw_hash, 'correct horse battery staple')
assert not is_correct_password(salt, pw_hash, 'Tr0ub4dor&3')
assert not is_correct_password(salt, pw_hash, 'rosebud')
Observe que:
- O uso de um sal de 16 bytes e 100.000 iterações de PBKDF2 correspondem aos números mínimos recomendados nos documentos do Python. Aumentar ainda mais o número de iterações tornará seus hashes mais lentos para calcular e, portanto, mais seguros.
os.urandom
sempre usa uma fonte criptograficamente segura de aleatoriedade
hmac.compare_digest
, usado em is_correct_password
, é basicamente apenas o ==
operador para strings, mas sem a capacidade de curto-circuito, o que o torna imune a ataques de temporização. Isso provavelmente não fornece nenhum valor de segurança extra , mas também não faz mal nenhum, então fui em frente e usei isso.
Para ver a teoria sobre o que torna um bom hash de senha e uma lista de outras funções apropriadas para fazer hash de senhas, consulte https://security.stackexchange.com/q/211/29805 .
t_sha.digest() + salt
. Você pode dividir o salt novamente mais tarde, quando tiver decodificado a senha hash salted, pois você sabe que a senha hash decodificada tem exatamente 32 bytes.