Skip to content

Instantly share code, notes, and snippets.

@jasonkeene
Last active October 7, 2015 20:08
Show Gist options
  • Save jasonkeene/3218462 to your computer and use it in GitHub Desktop.
Save jasonkeene/3218462 to your computer and use it in GitHub Desktop.
Generate and check password hashes for Ubersmith DE (salted sha1)
r"""Generate and check password hashes for Ubersmith DE (salted sha1).
Example use:
>>> my_new_hash = generate_hash('my_new_pass', 'salt')
>>> my_new_hash # store this in the database
'{ssha1}W77amZWRUSWjDLh04P/dlfsCvYdzYWx0\n'
>>> check_password('my_new_pass', my_new_hash)
True
>>> check_password('not_my_new_pass', my_new_hash)
False
"""
import base64
import hashlib
import random
def check_password(password, password_hash):
"""Return True if password matches password_hash, else return False."""
if isinstance(password, unicode):
password = password.encode('utf-8')
if password_hash.startswith('{ssha1}'):
password_hash = password_hash[7:]
decoded = base64.decodestring(password_hash)
if len(decoded) != 24:
raise ValueError('Invalid password hash.')
salt = decoded[20:] # 4 char salt
sha1_hash = decoded[:20] # 20 char hash
return hashlib.sha1(password + salt).digest() == sha1_hash
def generate_hash(password, salt=None):
"""Generate a hash of password with an optional four character salt."""
if isinstance(password, unicode):
password = password.encode('utf-8')
if not salt or len(salt) != 4:
salt = ''.join(chr(random.randrange(256)) for i in range(4))
sha1_hash = hashlib.sha1(password + salt).digest()
return '{ssha1}' + base64.encodestring(sha1_hash + salt)
if __name__ == '__main__':
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment