I'm doing a basic Python Flask application with a Postgres database using psycopg2. I'm having trouble setting up the user registration password hash as it appears I'm working with a string vs byte type. Fundalmentally, I'll get this error when doing the password re-hash on the login (after registration and initial hash)
hash_value = hashlib.pbkdf2_hmac(
# TypeError: a bytes-like object is required, not 'str'
Here is the relevant table setup:
CREATE TABLE IF NOT EXISTS myschema.mytable
(
--Unrelated fields...
password_hash character varying(500) COLLATE pg_catalog."default" NOT NULL,
salt character varying(100) COLLATE pg_catalog."default" NOT NULL,
--More unrelated fields...
)
This is how I'm inserting the data:
# Code above that is setting up a DB utility, configs, etc...
# Hash the password
salt = os.urandom(16)
iterations = 100000
hash_value = hashlib.pbkdf2_hmac(
'sha256',
password.encode('utf-8') + app_config['PEPPER'].encode('utf-8'),
salt,
iterations
)
password_hash = salt + hash_value
# Redacted extra fields
query = "INSERT INTO mytable (password_hash, salt) VALUES (%s, %s);"
params = (password_hash, salt)
# This kicks off the standard cursor execute, etc...
db.query(query, params)
And for the retrieval:
# Code above that is setting up a DB utility, configs, etc...
query = "SELECT password_hash, salt FROM mytable WHERE email = %s;"
params = (email,)
users = db.query(query, params)
db.close()
# No user found
if not users:
return False
db_password_hash, db_salt = users[0]
iterations = 100000
hash_value = hashlib.pbkdf2_hmac( # This will be the spot that throws the exception as it expects bytes for
'sha256',
password.encode('utf-8') + app_config['PEPPER'].encode('utf-8'),
db_salt,
iterations
)
# Then commence validation logic, etc...
I have tried using bytes(db_salt, 'utf-8') as it's really throwing the error on the salt field. However, this will not yield a successful rehash. I'll take recommendations - this is new development so if I need to do a postgres binary type I can do that too- whatever option makes sense here.
Thanks!
saltoriginall?? What is the value you get when you try to retrieve it?byteait might be easier.bytes(password.encode('utf-8')) + bytes(app_config['PEPPER'].encode('utf-8'))?