Skip to content

Instantly share code, notes, and snippets.

@lunaluxie
Created June 26, 2017 09:09
Show Gist options
  • Save lunaluxie/3b25d965af3f29e2457fe9b634fe21ff to your computer and use it in GitHub Desktop.
Save lunaluxie/3b25d965af3f29e2457fe9b634fe21ff to your computer and use it in GitHub Desktop.
Small utility that lets you compute and compare cryptographically secure password hashes
"""
Small utility that lets you compute and compare cryptographically secure password hashes
"""
def hash_password(password, salt=None, iterations=100000):
"""
Compute hash for a string using SHA1
input:
String: password
String: salt (use if you are comparing existing hash)
If empty, it generates new salt
Optional Input:
Int: iterations
How many times the hash hashes itself
should be consistent across your application
Return:
Tuple with the password hash and salt used
Example: (pass_hash, salt)
"""
# Do type checking
if not type(password) == type("String"):
raise TypeError("Password should be a string")
import hashlib, random, string
# if no salt is given
# generate 16 alphanumeric long salt using system random
if not salt:
salt = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(16))
# encode to make it compatible with hashlib algorithm
encoded_password = bytes(password, encoding='utf-8')
encoded_salt = bytes(salt, encoding='utf-8')
pass_hash = hashlib.sha1(encoded_password+encoded_salt).hexdigest()
# use iterative hashing
for _ in range(iterations):
pass_hash = hashlib.sha1(bytes(pass_hash, encoding="utf-8")).hexdigest()
return (pass_hash, salt)
def validate_password(password, pw_hash_tuple):
"""
Check if entered password matches a stored password hash
Input:
String: password
Tuple: pw_hash_tuple
of the scheme: (password_hash, salt)
Output:
Boolean: if they are identical.
"""
# Do input validation
if not len(pw_hash_tuple) == 2:
raise ValueError("pw_hash_tuple should have length 2")
if not type(password) == type('string'):
raise TypeError("password should be a string")
for item in pw_hash_tuple:
if not type(item) == type("string"):
raise TypeError("items in pw_hash_tuple should be strings")
stored_pw_hash = pw_hash_tuple[0]
stored_pw_salt = pw_hash_tuple[1]
# compute the hash of guesspassword using the same salt
user_pw_hash_tuple = hash_password(password, salt=stored_pw_salt)
# compare the two hashes
if user_pw_hash_tuple[0] == stored_pw_hash:
return True
else:
return False
# example
pw_hash_tuple = ('1023dd447f7212fd39b5a5df7c0d4e9fed0c22d5', 'XWZ3JIAWXXNSIMZA')
guess_password = "123456"
print (validate_password(guess_password, pw_hash_tuple)) # True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment