Warning
This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.security.passwords
import hashlib
from base64 import b64encode
from os import urandom
from galaxy.util import (
safe_str_cmp,
smart_str,
unicodify,
)
SALT_LENGTH = 12
KEY_LENGTH = 24
HASH_FUNCTION = "sha256"
COST_FACTOR = 100000
[docs]def hash_password(password):
"""
Hash a password, currently will use the PBKDF2 scheme.
"""
if password is None:
raise Exception("password cannot be None")
return hash_password_PBKDF2(password)
[docs]def check_password(guess, hashed):
"""
Check a hashed password. Supports either PBKDF2 if the hash is
prefixed with that string, or sha1 otherwise.
"""
if hashed.startswith("PBKDF2"):
if check_password_PBKDF2(guess, hashed):
return True
else:
# Passwords were originally encoded with sha1 and hexed
if safe_str_cmp(hashlib.sha1(smart_str(guess)).hexdigest(), hashed):
return True
# Password does not match
return False
[docs]def hash_password_PBKDF2(password):
# Generate a random salt
salt = b64encode(urandom(SALT_LENGTH))
# Apply the pbkdf2 encoding
hashed_password = pbkdf2_bin(password, salt, COST_FACTOR, KEY_LENGTH, HASH_FUNCTION)
encoded_password = unicodify(b64encode(hashed_password))
# Format
return f"PBKDF2${HASH_FUNCTION}${COST_FACTOR}${unicodify(salt)}${encoded_password}"
[docs]def check_password_PBKDF2(guess, hashed):
# Split the database representation to extract cost_factor and salt
name, hash_function, cost_factor, salt, encoded_original = hashed.split("$", 5)
# Hash the guess using the same parameters
hashed_guess = pbkdf2_bin(guess, salt, int(cost_factor), KEY_LENGTH, hash_function)
encoded_guess = unicodify(b64encode(hashed_guess))
return safe_str_cmp(encoded_original, encoded_guess)
[docs]def pbkdf2_bin(data, salt, iterations=COST_FACTOR, keylen=KEY_LENGTH, hashfunc=HASH_FUNCTION):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-256 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
data = smart_str(data)
salt = smart_str(salt)
return hashlib.pbkdf2_hmac(hashfunc, data, salt, iterations, keylen)