You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.9 KiB
66 lines
1.9 KiB
"""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): |
|
# pylint: disable=invalid-name |
|
"""Passlib handler for Werkzeug’s PBKDF2:SHA-256 passwords |
|
""" |
|
|
|
checksum_chars = '0123456789abcdef' |
|
checksum_size = 64 |
|
default_rounds = 150000 |
|
default_salt_chars = SALT_CHARS |
|
default_salt_size = 8 |
|
_digest = 'sha256' |
|
ident = u('pbkdf2:sha256') |
|
min_salt_size = 1 |
|
name = 'werkzeug_pbkdf2_sha256' |
|
salt_chars = SALT_CHARS |
|
|
|
# pylint: disable=arguments-differ |
|
@classmethod |
|
def from_string(cls, password_hash, **context): |
|
"""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')
|
|
|