散列给出不同的结果
Hashing gives different result
我正在使用 Python 和 MySql 来处理用户身份验证。我已经使用完全相同的方法通过 python 添加了用户,但是当我尝试进行“登录”/身份验证时,它不匹配。
这是我的验证码:
# Collecting data from users.
username=data['username']
password=data['password']
cur=mysql.connection.cursor()
# Checks if username exists.
check_username = cur.execute("SELECT * FROM `users` WHERE `username`=%s",[username])
if check_username > 0:
# Retrieves the correct salt of the user.
cur.execute("SELECT `salt` FROM `users` WHERE `username`=%s",[username])
get_salt = cur.fetchone()
# Generates the hashed password of the user.
hashed_password=(hashlib.sha256((str(password[0:2])+str(get_salt[0])+str(password[2:])).encode('utf-8')).hexdigest()).lower()
# Retrieves the hashed password of the user from the database.
cur.execute("SELECT `password` FROM `users` WHERE `username`=%s",[username])
get_password = cur.fetchone()
# Checks if identical.
if get_password[0] == hashed_password:
return jsonify("Authentication successful!"),201
else: return jsonify("Authentication failed!"),401
else: return 'Incorrect username. Please try again.'
hashed_password 与数据库中存储的 return 散列密码不同。
这是我用来插入用户的代码。
username=data['username']
password=data['password']
salt=data['salt']
cur=mysql.connection.cursor()
# Generates the hashed password of the user.
hashed_password=(hashlib.sha256((str(password[0:2])+str(salt[0])+str(password[2:])).encode('utf-8')).hexdigest()).lower()
# Adds user to database.
add_user = cur.execute(" INSERT INTO `users` (`username`, `password`, `salt`) VALUES (%s, %s, %s);",[username,hashed_password, salt])
有人知道这是什么原因吗?
查看插入代码,您似乎将 salt
视为 get_salt
元组,获取第一项,不知道它原来是什么,这可能是您问题的根源,因为我不会期望你得到的第一个盐在一个元组中。
这是一个有效的版本,它使用的是 SQLite 而不是 MySQL,但除了格式化之外的变化很小。
此外,我建议您使用 hashlib.hash.update()
而不是您庞大而复杂的一步散列。默认情况下 hexdigest 是小写的,所以不需要 .lower()
它。
# db setup
import hashlib
import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("CREATE TABLE users (username TEXT, salt TEXT, password TEXT)")
in_username = "ljmc"
in_salt = "verysecuresalt"
in_password = "p4assW0rD1!"
h = hashlib.sha256()
h.update(str(in_password[:2]).encode("utf-8"))
h.update(str(in_salt).encode("utf-8")) # here salt[0] is just b"v" not the whole salt
h.update(str(in_password[2:]).encode("utf-8"))
in_hashed_password = h.hexdigest()
cur.execute(
"INSERT INTO users VALUES (?, ?, ?)",
(in_username, in_salt, in_hashed_password), # then store whole salt
)
con.commit()
# user check
username = in_username
password = good_password
# Checks if username exists.
check_username = cur.execute(
"SELECT COUNT(*) FROM users WHERE username = ?", [username]
).fetchone()
if check_username[0] > 0:
# Retrieves the correct salt of the user.
cur.execute("SELECT salt FROM users WHERE username=?", [username])
get_salt = cur.fetchone() # get the whole salt
# Generates the hashed password of the user.
hashed_password = (
hashlib.sha256(
(str(password[0:2]) + str(get_salt[0]) + str(password[2:])).encode(
"utf-8"
)
).hexdigest()
).lower() # use the whole salt
# Retrieves the hashed password of the user from the database.
cur.execute("SELECT password FROM users WHERE username=?", [username])
get_password = cur.fetchone()
# Checks if identical.
if get_password[0] == hashed_password:
print("Authentication successful!")
else:
print("Authentication failed!")
正如其他评论所指出的,在一个查询中获取所有用户数据然后应用逻辑也会好很多,因此检查块看起来像这样。
cur.execute(
"SELECT username, salt, password FROM users WHERE username = ?",
(username,),
)
if user := cur.fetchone():
out_username, out_salt, out_password = user
h = hashlib.sha256()
h.update(str(password[:2]).encode("utf-8"))
h.update(str(out_salt).encode("utf-8"))
h.update(str(password[2:]).encode("utf-8"))
print(f"is the password {password} ?", out_password == h.hexdigest())
我正在使用 Python 和 MySql 来处理用户身份验证。我已经使用完全相同的方法通过 python 添加了用户,但是当我尝试进行“登录”/身份验证时,它不匹配。
这是我的验证码:
# Collecting data from users.
username=data['username']
password=data['password']
cur=mysql.connection.cursor()
# Checks if username exists.
check_username = cur.execute("SELECT * FROM `users` WHERE `username`=%s",[username])
if check_username > 0:
# Retrieves the correct salt of the user.
cur.execute("SELECT `salt` FROM `users` WHERE `username`=%s",[username])
get_salt = cur.fetchone()
# Generates the hashed password of the user.
hashed_password=(hashlib.sha256((str(password[0:2])+str(get_salt[0])+str(password[2:])).encode('utf-8')).hexdigest()).lower()
# Retrieves the hashed password of the user from the database.
cur.execute("SELECT `password` FROM `users` WHERE `username`=%s",[username])
get_password = cur.fetchone()
# Checks if identical.
if get_password[0] == hashed_password:
return jsonify("Authentication successful!"),201
else: return jsonify("Authentication failed!"),401
else: return 'Incorrect username. Please try again.'
hashed_password 与数据库中存储的 return 散列密码不同。
这是我用来插入用户的代码。
username=data['username']
password=data['password']
salt=data['salt']
cur=mysql.connection.cursor()
# Generates the hashed password of the user.
hashed_password=(hashlib.sha256((str(password[0:2])+str(salt[0])+str(password[2:])).encode('utf-8')).hexdigest()).lower()
# Adds user to database.
add_user = cur.execute(" INSERT INTO `users` (`username`, `password`, `salt`) VALUES (%s, %s, %s);",[username,hashed_password, salt])
有人知道这是什么原因吗?
查看插入代码,您似乎将 salt
视为 get_salt
元组,获取第一项,不知道它原来是什么,这可能是您问题的根源,因为我不会期望你得到的第一个盐在一个元组中。
这是一个有效的版本,它使用的是 SQLite 而不是 MySQL,但除了格式化之外的变化很小。
此外,我建议您使用 hashlib.hash.update()
而不是您庞大而复杂的一步散列。默认情况下 hexdigest 是小写的,所以不需要 .lower()
它。
# db setup
import hashlib
import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("CREATE TABLE users (username TEXT, salt TEXT, password TEXT)")
in_username = "ljmc"
in_salt = "verysecuresalt"
in_password = "p4assW0rD1!"
h = hashlib.sha256()
h.update(str(in_password[:2]).encode("utf-8"))
h.update(str(in_salt).encode("utf-8")) # here salt[0] is just b"v" not the whole salt
h.update(str(in_password[2:]).encode("utf-8"))
in_hashed_password = h.hexdigest()
cur.execute(
"INSERT INTO users VALUES (?, ?, ?)",
(in_username, in_salt, in_hashed_password), # then store whole salt
)
con.commit()
# user check
username = in_username
password = good_password
# Checks if username exists.
check_username = cur.execute(
"SELECT COUNT(*) FROM users WHERE username = ?", [username]
).fetchone()
if check_username[0] > 0:
# Retrieves the correct salt of the user.
cur.execute("SELECT salt FROM users WHERE username=?", [username])
get_salt = cur.fetchone() # get the whole salt
# Generates the hashed password of the user.
hashed_password = (
hashlib.sha256(
(str(password[0:2]) + str(get_salt[0]) + str(password[2:])).encode(
"utf-8"
)
).hexdigest()
).lower() # use the whole salt
# Retrieves the hashed password of the user from the database.
cur.execute("SELECT password FROM users WHERE username=?", [username])
get_password = cur.fetchone()
# Checks if identical.
if get_password[0] == hashed_password:
print("Authentication successful!")
else:
print("Authentication failed!")
正如其他评论所指出的,在一个查询中获取所有用户数据然后应用逻辑也会好很多,因此检查块看起来像这样。
cur.execute(
"SELECT username, salt, password FROM users WHERE username = ?",
(username,),
)
if user := cur.fetchone():
out_username, out_salt, out_password = user
h = hashlib.sha256()
h.update(str(password[:2]).encode("utf-8"))
h.update(str(out_salt).encode("utf-8"))
h.update(str(password[2:]).encode("utf-8"))
print(f"is the password {password} ?", out_password == h.hexdigest())