所以我是Python的新手,但我必须使用python或Web应用程序来创建登录系统。我决定使用tkinter进行GUI,这是经过几天的研究完成的,因此请随时告诉我,使用所找到的代码我还能做得更好。
该项目正在使用哈希和盐创建注册和登录系统。打开数据库时,必须在数据库中看到哈希和盐。到目前为止,我已经做到了。我可以注册,然后按登录时,它会检查数据库中是否有包含这些确切信息的行,并在控制台中将其返回,否则将不返回任何信息。
from tkinter import *
import os
import sqlite3
import hashlib
# Designing window for registration
def register():
global register_screen
register_screen = Toplevel(main_screen)
register_screen.title("Register")
register_screen.geometry("300x250")
global username
global password
global salt
global username_entry
global password_entry
global salt_entry
username = StringVar()
password = StringVar()
salt = StringVar()
Label(register_screen, text="Please enter details below", bg="blue").pack()
Label(register_screen, text="").pack()
username_lable = Label(register_screen, text="Username * ")
username_lable.pack()
username_entry = Entry(register_screen, textvariable=username)
username_entry.pack()
password_lable = Label(register_screen, text="Password * ")
password_lable.pack()
password_entry = Entry(register_screen, textvariable=password, show='*')
password_entry.pack()
salt_lable = Label(register_screen, text="Salt * ")
salt_lable.pack()
salt_entry = Entry(register_screen, textvariable=salt)
salt_entry.pack()
Label(register_screen, text="").pack()
Button(register_screen, text="Register", width=10, height=1, bg="blue", command=register_user).pack()
# Designing window for login
def login():
global login_screen
login_screen = Toplevel(main_screen)
login_screen.title("Login")
login_screen.geometry("300x250")
Label(login_screen, text="Please enter details below to login").pack()
Label(login_screen, text="").pack()
global username_verify
global password_verify
username_verify = StringVar()
password_verify = StringVar()
global username_login_entry
global password_login_entry
Label(login_screen, text="Username * ").pack()
username_login_entry = Entry(login_screen, textvariable=username_verify)
username_login_entry.pack()
Label(login_screen, text="").pack()
Label(login_screen, text="Password * ").pack()
password_login_entry = Entry(login_screen, textvariable=password_verify, show='*')
password_login_entry.pack()
Label(login_screen, text="").pack()
Button(login_screen, text="Login", width=10, height=1, command=login_verify).pack()
# Implementing event on register button
def register_user():
username_info = username.get()
password_info = password.get()
salt_info = salt.get()
salted = (password_info+salt_info)
hashed = hashlib.sha256(salted.encode()).hexdigest()
conn = sqlite3.connect('users.db')
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS user (Username TEXT, Password TEXT, Salt TEXT)')
c.execute('INSERT INTO user (Username, Password, salt) VALUES(?,?,?)', (username_info, password_info, salted))
conn.commit()
conn.close()
username_entry.delete(0, END)
password_entry.delete(0, END)
Label(register_screen, text="Registration Success", fg="green", font=("Calibri", 11)).pack()
# Implementing event on login button
def login_verify():
username1 = username_verify.get()
password1 = password_verify.get()
username_login_entry.delete(0, END)
password_login_entry.delete(0, END)
conn = sqlite3.connect('users.db')
c = conn.cursor()
c.execute("SELECT * FROM user WHERE Username='%s' AND Password='%s'" % (username1, password1))
print(c.fetchone())
# Designing popup for login success
def login_sucess():
global login_success_screen
login_success_screen = Toplevel(login_screen)
login_success_screen.title("Success")
login_success_screen.geometry("150x100")
Label(login_success_screen, text="Login Success").pack()
Button(login_success_screen, text="OK", command=delete_login_success).pack()
# Designing popup for login invalid password
def password_not_recognised():
global password_not_recog_screen
password_not_recog_screen = Toplevel(login_screen)
password_not_recog_screen.title("Success")
password_not_recog_screen.geometry("150x100")
Label(password_not_recog_screen, text="Invalid Password ").pack()
Button(password_not_recog_screen, text="OK", command=delete_password_not_recognised).pack()
# Designing popup for user not found
def user_not_found():
global user_not_found_screen
user_not_found_screen = Toplevel(login_screen)
user_not_found_screen.title("Success")
user_not_found_screen.geometry("150x100")
Label(user_not_found_screen, text="User Not Found").pack()
Button(user_not_found_screen, text="OK", command=delete_user_not_found_screen).pack()
# Deleting popups
def delete_login_success():
login_success_screen.destroy()
def delete_password_not_recognised():
password_not_recog_screen.destroy()
def delete_user_not_found_screen():
user_not_found_screen.destroy()
# Designing Main(first) window
def main_account_screen():
global main_screen
main_screen = Tk()
main_screen.geometry("300x250")
main_screen.title("Account Login")
Label(text="Select Your Choice", bg="blue", width="300", height="2", font=("Calibri", 13)).pack()
Label(text="").pack()
Button(text="Login", height="2", width="30", command=login).pack()
Label(text="").pack()
Button(text="Register", height="2", width="30", command=register).pack()
main_screen.mainloop()
main_account_screen()
使用此代码,它可以工作,但是我想从数据库中删除密码以及加盐的密码,而仅保留哈希密码和盐加的密码,所以:username;盐 ;哈希密码。现在我的问题是,当我登录时,如何比较哈希密码和输入的密码?我在想,在db中找到用户名>从db中检索salt>将其添加到输入的密码中>将其与哈希密码进行比较。还是应该在登录窗口中添加“输入您的盐分”框?
我将2个代码块更改为此:
def register_user():
username_info = username.get()
password_info = password.get()
salt_info = salt.get()
salted = (password_info+salt_info)
hashed = hashlib.sha256(salted.encode()).hexdigest()
conn = sqlite3.connect('users.db')
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS user (Username TEXT, Salt TEXT, Hashed TEXT)')
c.execute('INSERT INTO user (Username, Salt, Hashed) VALUES(?,?,?)', (username_info, salt_info, hashed))
conn.commit()
conn.close()
def login_verify():
username1 = username_verify.get()
password1 = password_verify.get()
username_login_entry.delete(0, END)
password_login_entry.delete(0, END)
conn = sqlite3.connect('users.db')
c = conn.cursor()
c.execute("SELECT * FROM user WHERE Username='%s' AND Hashed='%s'" % (username1, password1))
print(c.fetchone())
我投票从数据库中检索盐:)
Db应该包含盐和哈希密码。我可以找到的最佳建议是here
我特别喜欢这一部分:
“使用现有有效数据的非空列来构建盐(基于秘密加密密钥的河豚加密的用户名字符串通常在密码上是安全的。)请勿对盐使用单独的列。如果不能使用现有的列,将salt包含在与散列相同的列中。例如,对于128位salt使用前32个字符,对于160位哈希使用后40个字符。“