Pada Python 3.4, hashlib
modul di pustaka standar berisi fungsi derivasi kunci yang "dirancang untuk hashing sandi yang aman" .
Jadi gunakan salah satu dari itu, seperti hashlib.pbkdf2_hmac
, dengan garam yang dihasilkan menggunakan 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')
Perhatikan bahwa:
- Penggunaan salt 16-byte dan 100000 iterasi PBKDF2 cocok dengan angka minimum yang direkomendasikan dalam dokumen Python. Semakin meningkatkan jumlah iterasi akan membuat hash Anda lebih lambat untuk dihitung, dan karenanya lebih aman.
os.urandom
selalu menggunakan sumber keacakan yang aman secara kriptografis
hmac.compare_digest
, digunakan dalam is_correct_password
, pada dasarnya hanyalah ==
operator untuk string tetapi tanpa kemampuan untuk hubungan pendek, yang membuatnya kebal terhadap serangan waktu. Itu mungkin tidak benar-benar memberikan nilai keamanan tambahan , tetapi tidak ada salahnya, jadi saya telah melanjutkan dan menggunakannya.
Untuk teori tentang apa yang membuat hash kata sandi yang baik dan daftar fungsi lain yang sesuai untuk hash kata sandi dengan, lihat https://security.stackexchange.com/q/211/29805 .
t_sha.digest() + salt
. Anda dapat membagi salt lagi nanti ketika Anda telah memecahkan kode kata sandi hash yang diasinkan karena Anda tahu kata sandi hash yang didekodekan persis 32 byte.