Kể từ Python 3.4, hashlib
mô-đun trong thư viện chuẩn chứa các hàm dẫn xuất khóa được "thiết kế để băm mật khẩu an toàn" .
Vì vậy, hãy sử dụng một trong những thứ đó, chẳng hạn như hashlib.pbkdf2_hmac
, với muối được tạo ra bằng cách sử dụng 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')
Lưu ý rằng:
- Việc sử dụng muối 16 byte và 100000 lần lặp lại của PBKDF2 khớp với số lượng tối thiểu được đề xuất trong tài liệu Python. Việc tăng thêm số lần lặp sẽ làm cho các hàm băm của bạn được tính toán chậm hơn và do đó an toàn hơn.
os.urandom
luôn sử dụng một nguồn ngẫu nhiên an toàn bằng mật mã
hmac.compare_digest
, được sử dụng trong is_correct_password
, về cơ bản chỉ là ==
toán tử cho chuỗi nhưng không có khả năng đoản mạch, điều này làm cho nó miễn nhiễm với các cuộc tấn công định thời. Điều đó có lẽ không thực sự cung cấp thêm bất kỳ giá trị bảo mật nào , nhưng nó cũng không ảnh hưởng gì, vì vậy tôi đã tiếp tục và sử dụng nó.
Để biết lý thuyết về điều gì tạo nên một hàm băm mật khẩu tốt và danh sách các chức năng khác thích hợp để băm mật khẩu, hãy xem https://security.stackexchange.com/q/211/29805 .
t_sha.digest() + salt
. Bạn có thể tách muối ra một lần nữa sau khi bạn đã giải mã mật khẩu băm muối vì bạn biết mật khẩu băm được giải mã chính xác là 32 byte.