Pick a password hashing technique
Closed this issue · 4 comments
This plugin will use password hashes. Pick a technique for hashing them.
Python 3.6+ has scrypt
in the standard library, but it says it requires OpenSSL. I worry that's a dependency that won't be available everywhere. https://docs.python.org/3/library/hashlib.html#hashlib.scrypt
pbkdf2_hmac
is definitely available. Django has been using it for years.
https://nitratine.net/blog/post/how-to-hash-passwords-in-python/#hashing-passwords-with-pbkdf2_hmac is a good tutorial on using it.
Here's the relevant code in Django: https://github.com/django/django/blob/ca6c5e5fc23f2855a7094d195f09975b21a7ec3f/django/utils/crypto.py#L82-L89 and https://github.com/django/django/blob/ca6c5e5fc23f2855a7094d195f09975b21a7ec3f/django/contrib/auth/hashers.py#L247-L280
I'm going to replicate Django's storage format from https://github.com/django/django/blob/ca6c5e5fc23f2855a7094d195f09975b21a7ec3f/django/contrib/auth/hashers.py#L265
"%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
e.g. pbkdf2_sha256$180000$blahblah/blah/blah/1j=
I'm pretty much going to lift this Django code:
algorithm = "pbkdf2_sha256"
iterations = 260000
digest = hashlib.sha256
def encode(self, password, salt, iterations=None):
assert password is not None
assert salt and '$' not in salt
iterations = iterations or self.iterations
hash = pbkdf2(password, salt, iterations, digest=self.digest)
hash = base64.b64encode(hash).decode('ascii').strip()
return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash)
def decode(self, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
return {
'algorithm': algorithm,
'hash': hash,
'iterations': int(iterations),
'salt': salt,
}
def verify(self, password, encoded):
decoded = self.decode(encoded)
encoded_2 = self.encode(password, decoded['salt'], decoded['iterations'])
return constant_time_compare(encoded, encoded_2)
Here's my initial implementation:
datasette-auth-passwords/datasette_auth_passwords/utils.py
Lines 1 to 25 in 72fc155