Python 3.4부터 hashlib
표준 라이브러리 의 모듈 에는 "보안 암호 해싱을 위해 설계된" 키 파생 함수가 포함되어 있습니다. .
따라서 다음을 사용 hashlib.pbkdf2_hmac
하여 생성 된 솔트와 함께 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')
참고 :
- 16 바이트 솔트 사용과 PBKDF2 100000 회 반복은 Python 문서에서 권장하는 최소 숫자와 일치합니다. 반복 횟수를 더 늘리면 해시 계산 속도가 느려지므로 더 안전합니다.
os.urandom
항상 암호 학적으로 안전한 무작위 소스를 사용합니다.
hmac.compare_digest
에서 사용되는 is_correct_password
은 기본적으로 ==
문자열 의 연산자 일 뿐이지 만 단락 기능이 없으므로 타이밍 공격에 영향을받지 않습니다. 그 실제로 추가 보안 가치를 제공 하지 않지만 나쁘지 않으므로 계속해서 사용했습니다.
좋은 암호 해시를 만드는 이론과 암호를 해싱하는 데 적합한 다른 기능 목록은 https://security.stackexchange.com/q/211/29805를 참조 하십시오 .
t_sha.digest() + salt
. 디코딩 된 해시 암호가 정확히 32 바이트라는 것을 알고 있으므로 나중에 솔트 된 해시 암호를 디코딩 할 때 솔트를 다시 분할 할 수 있습니다.