Python+MySQL登录验证异常:读取哈希密码而非明文密码
问题根源分析
你的登录验证失败的核心原因非常明确:
- 注册阶段:你将用户输入的密码加上固定盐
"1qz",通过SHA256哈希后存入数据库 - 登录阶段:你直接用用户输入的明文密码和数据库里的哈希值做比对,二者格式、内容完全不同,自然验证失败
修复方案
你需要修改登录逻辑,严格按照和注册时完全一致的流程处理登录密码,再进行比对:
- 先根据用户名从数据库查询对应的哈希密码(而非同时用用户名+明文密码查询)
- 对用户登录输入的密码执行相同的加盐哈希操作
- 把生成的哈希值和数据库取出的哈希值进行比对
修改后的登录代码
def login_user(): attempts = 0 # Failed login attempts max_attempts = 3 # 建议把最大尝试次数改回3,更符合常规逻辑 while attempts < max_attempts: if UsernameEntry.get() == '' or PasswordEntry.get() == '': messagebox.showerror('Error', 'All fields are required!') break # 空字段时直接终止本轮循环,避免无效尝试计数 else: try: connect = mysql.connector.connect(host="localhost", user="root", password="somepassword123") cursor = connect.cursor() except: messagebox.showerror('Error', 'Connection is not established, try again') return cursor.execute('use users') # 第一步:根据用户名查询存储的哈希密码 query = 'select password from userdata where username=%s' cursor.execute(query, (UsernameEntry.get(),)) stored_hash = cursor.fetchone() if stored_hash is None: # 用户名不存在 messagebox.showerror('Error', 'Invalid username or password') attempts += 1 else: # 第二步:对登录输入的密码执行和注册完全一致的加盐哈希 input_password = PasswordEntry.get() salt = "1qz" salt = salt.encode('utf-8') password_and_salt = input_password.encode('utf-8') + salt input_hash = hashlib.sha256(password_and_salt).hexdigest() # 第三步:比对两个哈希值 if input_hash == stored_hash[0]: messagebox.showinfo('Welcome', 'Log In Successful') connect.close() cursor.close() return # 验证成功后直接退出函数 else: messagebox.showerror('Error', 'Invalid username or password') attempts += 1 if attempts == max_attempts: messagebox.showerror('Error', 'Too many failed login attempts') # 循环结束后关闭数据库连接 if 'connect' in locals(): connect.close() if 'cursor' in locals(): cursor.close()
额外优化建议
- 把固定盐
"1qz"抽成全局常量,或者单独写一个密码哈希工具函数,避免注册和登录两处的盐逻辑不一致(以后改盐只需要改一处) - 推荐给每个用户生成唯一的随机盐,注册时把盐和哈希密码一起存入数据库,登录时取出对应盐再处理密码,安全性远高于固定盐
- 登录循环里的连接关闭逻辑可以更严谨,避免异常情况下连接未释放
内容的提问来源于stack exchange,提问作者user2796592
相关产品推荐
相关产品推荐

