0

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!

4
  • "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" what does this mean exactly? What was the value for salt originall?? What is the value you get when you try to retrieve it? Commented Jan 21 at 4:05
  • 1
    but yeah, did you try making your salt column bytea it might be easier. Commented Jan 21 at 4:09
  • bytes(password.encode('utf-8')) + bytes(app_config['PEPPER'].encode('utf-8'))? Commented Jan 21 at 16:38
  • I ended up converting the database column as bytea and everything worked. Must of had something weird going on in the translation. I would get the raw memoryview and just call .tobytes() to compare the recomputed hash vs the one on the database. Commented Jan 23 at 2:53

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.