I'm working on a new python application for work that needs to verify existing user credentials in our database. Many of our relic applications were built on PHP's Symfony framework, which is where these password hashes and salts would have originated from. In the database the algorithm (sha1), the salt & the hashed password for users is retained. I'm trying to figure out how to correctly verify a password using this information in conjuncture the check_password_hash function of the werkzeug.security module. However, so far I've been unsuccessful.
For demonstration purposes I've created a test user and the database contains the following values for the user.
Test user values
algorithm: sha1
salt: e40e1e9addc186828a5554a71527342c
password (hashed): 784517f57fbe61179960739e29d7ae925aa4fd5b
The actual password of the test user is 123456
I've tried the following methods to verify the password.
Notes:
1. Hash format was adapted from the werkzeug.security documentation
2. Comparative Hash method was adapted from this StackOverflow answer
from werkzeug.security import generate_password_hash
from werkzeug.security import check_password_hash
# Attempt 1 - Results in False
check_password_hash('sha1$e40e1e9addc186828a5554a71527342c$784517f57fbe61179960739e29d7ae925aa4fd5b','123456')
# Attempt 2 - Results in False
check_password_hash('pbkdf2:sha1$e40e1e9addc186828a5554a71527342c$784517f57fbe61179960739e29d7ae925aa4fd5b','123456')
# Attempt 3
# Step 1: Append the salt_value to the given password and hash it using the same hash function.
generate_password_hash('123456$e40e1e9addc186828a5554a71527342c','sha1')
# sha1$9lUceSsd$60f7dcb3ff9c22d4613e59fcbfed0c463ee4189e
# Step 2: Compare the hash to the hash in the database
# 60f7dcb3ff9c22d4613e59fcbfed0c463ee4189e != 784517f57fbe61179960739e29d7ae925aa4fd5b
# Attempt 4 - Same steps as Attempt 3 except adding salt_length argument
# Step 1: Append the salt_value to the given password and hash it using the same hash function.
generate_password_hash('123456$e40e1e9addc186828a5554a71527342c','sha1',len('e40e1e9addc186828a5554a71527342c'))
# sha1$EbPv6DP0wMyu02UpA6ZYazFvvYvZTVI1$b8252583fea027d42af20c0d0f3eac3fbf468bd1
# Step 2: Compare the hash to the hash in the database
# b8252583fea027d42af20c0d0f3eac3fbf468bd1 != 784517f57fbe61179960739e29d7ae925aa4fd5b
Can anyone provide some insight on what I'm doing wrong? Should I try using a different library like passlib? I was hoping that this module would suffice since I'm familiar with it, having created a few of our existing python applications that utilize it for new user sign-ups, but in a separate database.
Edit - To show an alternative method to using werkzeug.security's check_password_hash function
import hashlib
# hashlib.sha1('{salt}{pw}'.encode()).hexdigest() == {pw_hash}
hashlib.sha1('e40e1e9addc186828a5554a71527342c123456'.encode()).hexdigest() == '784517f57fbe61179960739e29d7ae925aa4fd5b'
# True