簡體   English   中英

如何比較來自數據庫的散列密碼和輸入到使用 tkinter 制作的 GUI 登錄系統的登錄密碼

[英]How to compare hashed password from db and login password entered into GUI login system made with tkinter

所以我是 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 應該有鹽和散列密碼。 我能找到的關於如何做到這一點的最佳建議在這里

我特別喜歡這部分:

“使用現有有效數據的非空列來構建您的 salt(基於秘密加密密鑰的 blowfish 加密的用戶名字符串通常是加密安全的)。不要為 salt 使用單獨的列。如果您不能使用現有列,將您的鹽與您的散列合並在同一列中。例如,將前 32 個字符用於 128 位鹽,然后將后 40 個字符用於 160 位散列。”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM