36 lines
840 B
Python
36 lines
840 B
Python
import os
|
|
import base64
|
|
import hashlib
|
|
import secrets
|
|
|
|
ALGORITHM = "pbkdf2_sha256"
|
|
|
|
def crypt(password: str, salt: bytes=None, iterations=260000) -> str:
|
|
if salt is None:
|
|
salt = os.urandom(16)
|
|
|
|
hashed = hashlib.pbkdf2_hmac(
|
|
'sha256', bytes(password, 'utf-8'), salt, iterations
|
|
)
|
|
|
|
return '$'.join([
|
|
ALGORITHM,
|
|
str(iterations),
|
|
str(base64.b64encode(salt), 'ascii'),
|
|
str(base64.b64encode(hashed), 'ascii')
|
|
])
|
|
|
|
def compare(password: str, crypted: str) -> bool:
|
|
parts = crypted.split('$', 4)
|
|
|
|
if len(parts) != 4:
|
|
return False
|
|
|
|
algorithm, iterations, salt, hashed = parts
|
|
|
|
if algorithm != ALGORITHM:
|
|
return False
|
|
|
|
new_crypted = crypt(password, base64.b64decode(salt), int(iterations))
|
|
|
|
return secrets.compare_digest(crypted, new_crypted)
|