You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python+MySQL登录验证异常:读取哈希密码而非明文密码

问题根源分析

你的登录验证失败的核心原因非常明确:

  • 注册阶段:你将用户输入的密码加上固定盐"1qz",通过SHA256哈希后存入数据库
  • 登录阶段:你直接用用户输入的明文密码和数据库里的哈希值做比对,二者格式、内容完全不同,自然验证失败
修复方案

你需要修改登录逻辑,严格按照和注册时完全一致的流程处理登录密码,再进行比对:

  1. 先根据用户名从数据库查询对应的哈希密码(而非同时用用户名+明文密码查询)
  2. 对用户登录输入的密码执行相同的加盐哈希操作
  3. 把生成的哈希值和数据库取出的哈希值进行比对
修改后的登录代码
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:15:50