I've written a method for hashing passwords by using hashlib. I allow the user to send a password through a POST method, which is received by Flask and the password is subsequently hashed so that the hash can be checked against a stored var to see if it's the same.
It works great both when a correct or an incorrect password is sent for the first time. But if the user sends a wrong password on the first POST and then tries again with the correct password, it fails. (One could also think of it as failing if the first try was a success and the user keeps on trying, but I don't care about that for now.)
I was able to narrow the problem down to hashlibs update function
hash.update(arg) Update the hash object with the string arg. Repeated calls are equivalent to a single call with the concatenation of all the arguments: m.update(a); m.update(b) is equivalent to m.update(a+b).
I wanted to know how can I disable the concatenation upon repeated calls. It doesn't matter if it's a hacky workaround.
Here's my code in case it's useful:
h = hashlib.sha256()
VALID_USERNAME = 'admin'
VALID_PASSW_HASH = "210ce034be6d826a451a4261d70494148c5d7101627335ccacf8e00a711bcc5d"
@app.route('/api/queue/auth', methods=['POST'])
def auth():
username = request.json.get('username')
password = request.json.get('password')
if bool(username) is False or bool(password) is False:
return "\nPlease fill in both fields.\n", 400
passwordBytes = password.encode(encoding='UTF-8',errors='strict')
h.update(passwordBytes)
if h.hexdigest() != VALID_PASSW_HASH or username != VALID_USERNAME:
return "\nPlease check your username and password, and try again.\n", 401
r.set('auth', 'true')
return "Access Granted.\n", 200
Additional notes:
Just move the first line out of the global scope into the auth()
function:
VALID_USERNAME = 'admin'
VALID_PASSW_HASH = "210ce034be6d826a451a4261d70494148c5d7101627335ccacf8e00a711bcc5d"
@app.route('/api/queue/auth', methods=['POST'])
def auth():
username = request.json.get('username')
password = request.json.get('password')
if bool(username) is False or bool(password) is False:
return "\nPlease fill in both fields.\n", 400
passwordBytes = password.encode(encoding='UTF-8',errors='strict')
h = hashlib.sha256()
h.update(passwordBytes)
if h.hexdigest() != VALID_PASSW_HASH or username != VALID_USERNAME:
return "\nPlease check your username and password, and try again.\n", 401
r.set('auth', 'true')
return "Access Granted.\n", 200
or even better, refactor the hashing of the password to a different function:
VALID_USERNAME = 'admin'
VALID_PASSW_HASH = "210ce034be6d826a451a4261d70494148c5d7101627335ccacf8e00a711bcc5d"
def hash_password(password):
passwordBytes = password.encode(encoding='UTF-8',errors='strict')
h = hashlib.sha256()
h.update(passwordBytes)
return h.hexdigest()
@app.route('/api/queue/auth', methods=['POST'])
def auth():
username = request.json.get('username')
password = request.json.get('password')
if bool(username) is False or bool(password) is False:
return "\nPlease fill in both fields.\n", 400
if hash_password(password) != VALID_PASSW_HASH or username != VALID_USERNAME:
return "\nPlease check your username and password, and try again.\n", 401
r.set('auth', 'true')
return "Access Granted.\n", 200