66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
|
"""Passlib module to understand hashed password format of Werkzeug
|
||
|
"""
|
||
|
|
||
|
__version__ = '0.1.0'
|
||
|
|
||
|
from base64 import b64encode
|
||
|
|
||
|
from passlib.crypto.digest import pbkdf2_hmac
|
||
|
from passlib.exc import InvalidHashError
|
||
|
from passlib.registry import register_crypt_handler_path
|
||
|
import passlib.utils.handlers as uh
|
||
|
from passlib.utils.binary import AB64_CHARS, ab64_decode, ab64_encode
|
||
|
from passlib.utils.compat import u
|
||
|
|
||
|
SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||
|
|
||
|
|
||
|
class werkzeug_pbkdf2_sha256(uh.HasSalt, uh.HasRounds, uh.GenericHandler):
|
||
|
checksum_chars = AB64_CHARS
|
||
|
checksum_size = 64
|
||
|
default_rounds = 150000
|
||
|
default_salt_chars = SALT_CHARS
|
||
|
default_salt_size = 8
|
||
|
_digest = 'sha256'
|
||
|
ident = u('pbkdf2:sha256')
|
||
|
max_rounds = 0xffffffff
|
||
|
max_salt_size = None
|
||
|
min_salt_size = 1
|
||
|
name = 'werkzeug_pbkdf2_sha256'
|
||
|
salt_chars = SALT_CHARS
|
||
|
setting_kwds = ('salt', 'salt_size')
|
||
|
werkzeug_name = 'pbkdf2:sha256'
|
||
|
|
||
|
@classmethod
|
||
|
def from_string(cls, password_hash):
|
||
|
"""Create a new hash object from a string
|
||
|
"""
|
||
|
|
||
|
try:
|
||
|
full_method, salt, checksum = password_hash.split('$')
|
||
|
except ValueError as exc:
|
||
|
raise InvalidHashError(cls) from exc
|
||
|
|
||
|
method, digest, rounds = full_method.split(':')
|
||
|
|
||
|
if ':'.join((method, digest)) != cls.ident:
|
||
|
raise InvalidHashError(cls)
|
||
|
|
||
|
if checksum:
|
||
|
bytes.fromhex(checksum)
|
||
|
|
||
|
return cls(salt=salt, checksum=checksum, rounds=int(rounds))
|
||
|
|
||
|
def to_string(self):
|
||
|
full_method = ':'.join((self.ident, str(self.rounds)))
|
||
|
|
||
|
return '$'.join((full_method, self.salt, self.checksum))
|
||
|
|
||
|
def _calc_checksum(self, secret):
|
||
|
checksum = pbkdf2_hmac(self._digest, secret, self.salt, self.rounds)
|
||
|
|
||
|
return checksum.hex()
|
||
|
|
||
|
|
||
|
register_crypt_handler_path('werkzeug_pbkdf2_sha256', 'passlib_werkzeug')
|