使用bcrypt校验密码时哈希值引号去除问题求助
解决bcrypt校验存储于TXT文件中带引号哈希密码的问题
核心问题
你存储在database.txt中的哈希密码是字符串化的字节对象(比如b'$2b$12$...')或者带引号的字符串(比如"$2b$12$..."),而bcrypt.checkpw()需要的是原始字节类型的哈希值,直接去掉引号或b前缀再编码会导致哈希格式错误,校验失败。
解决方案
步骤1:统一哈希值的解析逻辑
不管存储的是带b'前缀的字符串还是带双引号的字符串,都需要:
- 去除所有包裹的引号(单/双引号)
- 去除开头的
b前缀(如果存在) - 将处理后的字符串转换为字节类型(用
utf-8编码)
步骤2:修正代码中的错误点
- 原代码中
elif y != None or x == None逻辑错误,应改为elif y != None and x == None,避免逻辑冲突 - 读取文件时用
with语句自动关闭文件,更安全 - 处理空文件的逻辑错误:
readlines()返回空列表而非None,判断应改为if not contant:
修正后的完整代码
import bcrypt def Log_in(): # 打印分隔线 print("-"*70) # 提示用户输入用户名/邮箱及密码 msg0 = "请输入您的用户名或电子邮箱地址" msg1 = "请输入您的密码" user_input = input(f"{msg0:45}| ") user_password = input(f"{msg1:45}| ") # 修正原拼写错误:user_pasword -> user_password print("-"*70) # 用with语句安全读取文件 email_list = [] username_list = [] password_list = [] with open("database.txt", 'r') as db: contant = db.readlines() # 处理文件内容 for line in contant: line = line.strip() # 先去除行首尾的换行/空格 if not line: continue # 跳过空行 parts = line.split("| ") if len(parts) != 4: continue # 跳过格式错误的行 a, b, c, d = parts email_list.append(a.strip()) username_list.append(b.strip()) password_list.append(d.strip()) # 检查输入的用户名/邮箱是否存在 if user_input in username_list or user_input in email_list: x = username_list.index(user_input) if user_input in username_list else None y = email_list.index(user_input) if user_input in email_list else None # 获取对应的哈希值索引 target_idx = x if x is not None else y if target_idx is None: print("密码错误") Log_in() return # 处理哈希值:去除引号、b前缀,转换为字节 hashed_str = password_list[target_idx] # 去除所有引号(单/双) hashed_str = hashed_str.replace("'", "").replace('"', '') # 去除开头的b前缀(如果存在) if hashed_str.startswith('b'): hashed_str = hashed_str[1:] # 转换为字节类型 hashed_bytes = hashed_str.encode('utf-8') # 执行校验 if bcrypt.checkpw(user_password.encode('utf-8'), hashed_bytes): print("欢迎登录") else: print("密码错误") Log_in() else: print("该用户名或电子邮箱不存在") Log_in() # 主函数 if __name__ == "__main__": Log_in()
关键处理说明
- 哈希值清理:通过
replace去除所有单双引号,再判断并去除开头的b前缀,确保得到纯哈希字符串,再编码为字节。 - 逻辑简化:合并用户名和邮箱的索引判断,避免重复代码和逻辑错误。
- 文件读取优化:使用
with语句自动管理文件资源,跳过空行和格式错误的行,提升鲁棒性。 - 拼写修正:修正了原代码中
user_pasword的拼写错误,避免变量名问题。
内容的提问来源于stack exchange,提问作者Omar Attia
相关产品推荐
相关产品推荐

