Bcrypt salt treating byte object as string and wont hash password
已回答
我有一个带有Postgres DB的Flask Web应用程序。 我正在尝试实现数据库
用bcrypt进行盐腌,但似乎我的字节表示形式被视为字符串。 需要说明的是:我正在毫无问题地创建哈希密码,但是在授权登录尝试时,使用传递的salt生成比较哈希是行不通的。 这是我尝试登录时发生的错误堆栈:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | lost/app/views/login.py", line 37, in login authorized = helpers.authorize(username, password) lost/app/helpers.py", line 108, in authorize return _check_hash_for_user(username, password) lost/app/helpers.py", line 93, in _check_hash_for_user generated_hash = _recreate_hash(password, _get_salt_for_user(username)) lost/app/helpers.py", line 100, in _recreate_hash hash_pass = bcrypt.hashpw(password.encode('utf-8'), salt) lost/venv/lib/python3.6/site-packages/bcrypt/__init__.py", line 62, in hashpw raise TypeError("Unicode-objects must be encoded before hashing") |
我的
1 2 3 4 5 | CREATE TABLE users ( user_pk SERIAL PRIMARY KEY, username VARCHAR(16) UNIQUE NOT NULL, salt VARCHAR(72) NOT NULL, password VARCHAR(256) NOT NULL |
我的登录视图的相关方面
1 2 3 4 5 6 7 8 | username = request.form.get('username', None) password = request.form.get('password', None) # If user exists... authorized = helpers.authorize(username, password) if authorized: # login... |
这是我创建用户密码和盐的方法
1 2 | salt=bcrypt.gensalt(12) password = bcrypt.hashpw(password.encode('utf-8'), salt) |
helpers.py的auth方面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | def _get_hash_for_user(username): password = db_query("SELECT password FROM users WHERE username=%s;", [username])[0][0] return password def _get_salt_for_user(username): salt=db_query("SELECT salt FROM users WHERE username=%s;", [username])[0][0] return salt def _create_password_hash(password): salt=bcrypt.gensalt(16) hashed_pass = bcrypt.hashpw(password, salt) return hashed_pass, salt def _check_hash_for_user(username, password): stored_hash = _get_hash_for_user(username) generated_hash = _recreate_hash(password, _get_salt_for_user(username)) return stored_hash == generated_hash def _recreate_hash(password, salt): hash_pass = bcrypt.hashpw(password.encode('utf-8'), salt) return hash_pass def authorize(username, password): return _check_hash_for_user(username, password) |
编辑:
应某人的要求,我现在使用
如
重现MCVE错误:
1 2 3 4 | import bcrypt salt=str(bcrypt.gensalt()) pw ="Dagg Durneden Co. Mfgrs. Green Hood Shirts" pw_hash = bcrypt.hashpw(pw.encode('utf-8'), salt) |
固定:
1 | pw_hash = bcrypt.hashpw(pw.encode('utf-8'), bytes(salt)) |
OP回答他自己的问题-感谢大家的帮助
将哈希作为varchars存储在我的数据库中并继续在我的代码中翻转它们并不明智。 取而代之的是,我更改了users表,以将哈希密码和盐存储为BYTEA数据类型。
之后,我通过将返回类型强制转换为
所以...
1 2 3 4 5 6 7 8 | def _get_hash_for_user(username): password = byte(db_query("SELECT password FROM users WHERE username=%s;", [username])[0][0]) return password def _get_salt_for_user(username): salt=byte(db_query("SELECT salt FROM users WHERE username=%s;", [username])[0][0]) return salt |