Python密码管理器代码报错排查:Tkinter回调及SQL语法等3类错误
Python密码管理器错误排查与修复
问题描述
开发Python密码管理器时,解决之前的2个问题后仍出现3类错误:
- Tkinter回调异常(此前已存在),报错栈指向
tkinter/__init__.py的__call__方法; checkPassword函数调用getmasterPassword()时出现异常;getmasterPassword中的SQLite语句存在语法错误,提示near "password": syntax error。
详细报错信息
- C:\Users####\PycharmProjects\pythonProject8\main.py
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users####\AppData\Local\Programs\Python\Python311\Lib\tkinter_init_.py", line 1948, in call
return self.func(*args)
^^^^^^^^^^^^^^^^- File "C:\Users####\PycharmProjects\pythonProject8\main.py", line 78, in checkPassword
match = getmasterPassword()
^^^^^^^^^^^^^^^^^^^- File "C:\Users####\PycharmProjects\pythonProject8\main.py", line 73, in getmasterPassword
cursor.execute("SELECT * FROM masterpassword WHERE id = 1 password= ?", [check_hashed_password])
sqlite3.OperationalError: near "password": syntax error
错误原因与修复步骤
1. SQLite语法错误(核心触发点)
getmasterPassword函数的SQL查询语句中,WHERE子句的两个条件id=1和password=?之间缺少逻辑运算符AND,直接导致SQL语法错误。
修复前代码:
cursor.execute("SELECT * FROM masterpassword WHERE id = 1 password = ?", [(checkHashedPassword)])
修复后代码:
cursor.execute("SELECT * FROM masterpassword WHERE id = 1 AND password = ?", [checkHashedPassword])
2. 密码存储与验证的逻辑错误
savePassword函数中,hashedPassword = txt.get仅引用了方法对象,未调用get()获取输入值,且未使用导入的hashlib进行密码哈希(明文存储不安全):
修复前:
修复后:hashedPassword = txt.gethashedPassword = hashlib.sha256(txt.get().encode()).hexdigest()getmasterPassword函数中,需对用户输入的密码进行同样的哈希处理,才能与数据库中存储的哈希值匹配:
修复后代码片段:input_password = txt.get() hashed_input = hashlib.sha256(input_password.encode()).hexdigest() cursor.execute("SELECT * FROM masterpassword WHERE id = 1 AND password = ?", [hashed_input])
3. Tkinter回调异常
该异常是由上述SQL错误和逻辑错误导致的——当Tkinter回调函数(如checkPassword)执行时抛出未捕获的异常,就会触发回调异常。修复上述所有错误后,该异常会自动消失。
完整修正后的代码
import sqlite3 import hashlib from tkinter import * # 数据库初始化 with sqlite3.connect("password_vault.db") as db: cursor = db.cursor() # 创建主密码表(如果不存在) cursor.execute(""" CREATE TABLE IF NOT EXISTS masterpassword( id INTEGER PRIMARY KEY, password TEXT NOT NULL); """) window = Tk() window.title("Password Vault") def firstScreen(): window.geometry("250x175") lbl = Label(window, text="Create Master Password") lbl.config(anchor=CENTER) lbl.pack() # 密码输入框隐藏显示内容 txt = Entry(window, width=20, show="*") txt.pack() txt.focus() lbl1 = Label(window, text="Re-Enter Password") lbl1.pack() txt1 = Entry(window, width=20, show="*") txt1.pack() txt1.focus() lbl2 = Label(window) lbl2.pack() def savePassword(): if txt.get() == txt1.get(): # 对密码进行SHA256哈希加密 hashedPassword = hashlib.sha256(txt.get().encode()).hexdigest() insert_password = """INSERT INTO masterpassword(password) VALUES(?)""" cursor.execute(insert_password, [hashedPassword]) db.commit() passwordVault() else: lbl2.config(text="Passwords do not match") btn = Button(window, text="Save", command=savePassword) btn.pack(pady=10) def loginScreen(): window.geometry("250x100") lbl = Label(window, text="Enter Master Password") lbl.config(anchor=CENTER) lbl.pack() txt = Entry(window, width=20, show="*") txt.pack() txt.focus() lbl1 = Label(window) lbl1.pack() def getmasterPassword(): # 获取输入密码并哈希 input_password = txt.get() hashed_input = hashlib.sha256(input_password.encode()).hexdigest() # 修复SQL语法错误:添加AND连接条件 cursor.execute("SELECT * FROM masterpassword WHERE id = 1 AND password = ?", [hashed_input]) return cursor.fetchall() def checkPassword(): try: match = getmasterPassword() if match: passwordVault() else: txt.delete(0, END) lbl1.config(text="Wrong Password") except Exception as e: lbl1.config(text=f"Error: {str(e)}") btn = Button(window, text="Submit", command=checkPassword) btn.pack(pady=10) def passwordVault(): # 清空当前界面所有组件 for widget in window.winfo_children(): widget.destroy() window.geometry("700x350") lbl = Label(window, text="Password Vault") lbl.config(anchor=CENTER) lbl.pack() # 判断是否已有主密码,决定进入登录或创建界面 cursor.execute("SELECT * FROM masterpassword") if cursor.fetchall(): loginScreen() else: firstScreen() window.mainloop()
内容的提问来源于stack exchange,提问作者noodle
相关产品推荐
相关产品推荐

