salt = base64.b64decode(salt_b64) password_hash = base64.b64decode(password_hash_b64) except (ValueError, TypeError): return False if iterations <= 0: return False attempt_hash = _encrypt(attempt, salt, iterations, len(password_hash)) return constant_time.bytes_eq(attempt_hash, password_hash) def _generate_salt(salt_len): """Generates random string for salt.""" return os.urandom(salt_len) def _encrypt(password, salt, iterations, hash_len): """Performs key derivation according to the PKCS#5 standard (v2.0), by means of the PBKDF2 algorithm using HMAC-SHA256 as a pseudorandom function. """ backend = default_backend() kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=hash_len, salt=salt, iterations=iterations, backend=backend) return kdf.derive(password) registerScheme('PBKDF2-SHA256', PBKDF2DigestScheme())
def initialize(registrar): registerScheme('sha1', DjangoSHAScheme())
class Argon2Scheme(SSHADigestScheme): """ scheme follows this format... argon:salt:hashed """ ph = argon2.PasswordHasher() def _format(self, pw): return b2a_base64(self.ph.hash(pw)) def encrypt(self, pw): pw = str(pw) return self._format(pw) def validate(self, reference, attempt): try: ref = a2b_base64(reference) except binascii.Error: # Not valid base64. return False try: return self.ph.verify(ref, attempt) except argon2.exceptions.Argon2Error: return False registerScheme('argon2', Argon2Scheme()) # we patch this to be default because plone doesn't provide a param pw_encrypt.func_defaults = ('argon2', )