hynek / argon2-cffi

Secure Password Hashes for Python

Home Page:https://argon2-cffi.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

hash function return + / verify issue with sqlite

ThomasGustafson opened this issue · comments

I am working on an app in python that requires user verification and I decided to use argon 2.

Creating and verifying the passwords works on the insert end however when I try to pull the information from my sqlite database it throws an verification error despite the values matching.

I have also tried to hash the password in my hash password function using the same hasher and parameters but it gives me a completely different hash then when I try to verify it will throw a password does not match the supplied hash error. I am not sure what I am doing wrong?

here is the code for the create user and main window

main window

import sqlite3

import wx
from argon2 import PasswordHasher, Type
import re

import CreateUserWindow
import MediaReelzWindow
import UpdateUserWindow
from User import User


def CreateUsersTable():
    try:
        con = sqlite3.connect('Reelz.db')
        cursor = con.cursor()
        sql = '''CREATE TABLE IF NOT EXISTS Users (
                 userId INTEGER PRIMARY KEY not Null ,
                 userName TEXT not NULL ,
                 hash  TEXT not NULL,
                 securityQuestion1 TEXT not NULL, 
                 securityQuestion1Answer TEXT not NULL, 
                 securityQuestion2 TEXT not NULL,
                 securityQuestion2Answer TEXT not NULL,
                 securityQuestion3 TEXT not NULL,
                 securityQuestion3Answer TEXT not NULL
                  ); '''
        cursor.execute(sql)
        con.commit()
        con.close()
    except:
        print("we had a problem creating the users table")


def CreateReelzTable():
    try:
        con = sqlite3.connect('Reelz.db')
        cursor = con.cursor()
        sql = ''' CREATE TABLE IF NOT EXISTS Reelz (
            reelId INTEGER PRIMARY KEY not Null ,
            reelName TEXT not NULL ,
            reelArtist TEXT not NULL ,
            reelYear INTEGER ,
            reelType TEXT not NULL ,
            reelNotes TEXT ,
            reelOwn TinyInt,
            reelWant TinyInt
            ); '''
        cursor.execute(sql)
        con.commit()
        con.close()
    except:
        print("we had a problem creating the Reelz Table")


def CreateUsers_ReelzsTable():
    try:
        con = sqlite3.connect('Reelz.db')
        cursor = con.cursor()
        sql = ''' CREATE TABLE IF NOT EXISTS User_Reels (
            UserReelId INTEGER PRIMARY KEY not Null,
            userId INTEGER NOT NULL,
            reelId INTEGER NOT NULL,
            FOREIGN KEY  (userId) REFERENCES Users (userId),
            FOREIGN KEY (reelId) REFERENCES packs (packId) 
            ); '''
        cursor.execute(sql)
        con.commit()
        con.close()
    except:
        print("we had a problem creating the Users Reelzs  Table")

    #  Login main Frame


class LoginFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title=" Login Window", size=(400, 500))
        loginpanel = LoginPanel(self)
        self.Show()


class LoginPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, size=(400, 500))
        self.LoginLabel = wx.StaticText(self, label="Log In To Media Reelz", pos=(180, 70))
        self.UserNameLabel = wx.StaticText(self, label="User Name", pos=(50, 150))
        self.PassWordLabel = wx.StaticText(self, label="PassWord", pos=(50, 240))
        self.UserNameTextField = wx.TextCtrl(self, value="", pos=(130, 145))
        self.PassWordField = wx.TextCtrl(self, value="", pos=(125, 240))
        self.CreateUserButton = wx.Button(self, pos=(50, 325))
        self.CreateUserButton.SetLabel("Create User")
        self.CreateUserButton.Bind(wx.EVT_BUTTON, CreateUserWindow.CreateUserFrame)
        self.LoginButton = wx.Button(self, pos=(160, 325))
        self.LoginButton.SetLabel("Login")
        self.LoginButton.Bind(wx.EVT_BUTTON, self.verifyUserCredentials)
        self.UpdateUserButton = wx.Button(self, pos=(270, 325))
        self.UpdateUserButton.SetLabel("Update User")
        self.UpdateUserButton.Bind(wx.EVT_BUTTON, UpdateUserWindow.UpdateUsersFrame)
        self.ForgotPasswordButton = wx.Button(self, pos=(120, 400), size=(150, 25))
        self.ForgotPasswordButton.SetLabel("Forgot PassWord")

    def verifyUserCredentials(self, event):
        self.HashPassword(self.PassWordField.GetValue())

    def HashPassword(self, userpassword):
        print(userpassword)

        print(self.UserNameTextField.GetValue())
        storedHash = self.getStoredHash(self.UserNameTextField.GetValue())
        convertedHash = re.sub((''), "", storedHash)

        print(CreateUserWindow.hasher.hash(self.PassWordField.GetValue()))
        print(storedHash)

        print(" stored hash next line ( line 118)")
        print(storedHash)
        verify = CreateUserWindow.hasher.verify(convertedHash, userpassword)

        if verify:

            MediaReelzWindow.MediaReelzWindowFrame("media reelzs viewer")
        else:
            print("we had a problem verifying the user credentials")

    def getStoredHash(self, userName):

        global result
        userNameForHashRetrevial = [userName]

        try:
            con = sqlite3.connect('reelz.db')
            cursor = con.cursor()
            sql = ''' SELECT  hash From Users Where userName = ? '''
            cursor.execute(sql, userNameForHashRetrevial)
            result = cursor.fetchone()
            print(' result should be on next line ')
            print(result)
            con.commit()
            con.close()
            print(" User Hash has been found")
            return result[0]








        except:
            print(" user hash not found  please check your entry and  try again")

    def setVerifiedUserId(self):

        username = self.UserNameTextField.GetValue()
        storedHash = self.getStoredHash(self.UserNameTextField.GetValue())
        userCredentialsForRetreival = [username, storedHash]
        try:
            con = sqlite3.connect('Reelz.db')
            cursor = con.cursor()
            sql = ''' SELECT  userId From Users Where userName = ? , AND hash = ? '''
            cursor.execute(sql, userCredentialsForRetreival)
            userIdResult = cursor.fetchone()

            print(userIdResult)
            #  we are going to have to trouble shoot this giving an imput error
            User.user_id = userIdResult
            con.commit()
            con.close()
        except:
            print(" we had a problem setting the user id")


if __name__ == '__main__':
    app = wx.App(False)
    frame = LoginFrame()
    CreateUsersTable()
    CreateReelzTable()
    CreateUsers_ReelzsTable()
    app.MainLoop()

create user

import wx
import sqlite3
from argon2 import *

hasher = PasswordHasher()


class CreateUserFrame(wx.Frame):

    def __init__(self, title, parent=None):
        wx.Frame.__init__(self, title='Login window', size=(800, 730), parent=parent)
        questions = ["Please select a security Question", "What is your favorite color?", "First pets name?",
                     "favorite musical artist or band?", "Favorite animal?", "favorite tv Show"]
        self.CreateUserPanel = wx.Panel(self, size=(800, 730))
        self.SecurityQuestion1AnswerTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 120))
        self.SecurityQuestion2ChoiceBox = wx.Choice(self.CreateUserPanel, choices=questions, pos=(220, 180))
        self.SecurityQuestion2ChoiceBox.SetSelection(0)
        self.SecurityQuestion2AnswerTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 240))
        self.SecurityQuestion3Label = wx.StaticText(self.CreateUserPanel, label="Security Question 3", pos=(98, 300))
        self.SecurityQuestion3AnswerLabel = wx.StaticText(self.CreateUserPanel, label="Answer 3", pos=(150, 360))
        self.NewUserKeyLabel = wx.StaticText(self.CreateUserPanel, label="User Key", pos=(150, 480))
        self.ConfirmNewUserKeyLabel = wx.StaticText(self.CreateUserPanel, label="Confirm User Key", pos=(98, 540))
        self.ShowConfirmNewUserKeyLabel = wx.StaticText(self.CreateUserPanel, label=" Show Text", pos=(500, 540))
        self.NewUserNameTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 416))
        self.ConfirmNewUserKeyTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 540))
        self.ConfirmNewUserKeyTextInput.Show(False)
        self.ShowNewUserKeyCheckBox = wx.CheckBox(self.CreateUserPanel, label="", pos=(480, 480))
        self.ShowNewUserKeyCheckBox.Bind(wx.EVT_CHECKBOX, self.showNewUserKeyText)
        self.CreateUserButton = wx.Button(self.CreateUserPanel, pos=(380, 610))
        self.CreateUserButton.SetLabel("Create User")
        self.CreateUserButton.Bind(wx.EVT_BUTTON, self.VerifyUniqueUserName)
        self.ShowConfirmNewUserKeyCheckBox = wx.CheckBox(self.CreateUserPanel, label="", pos=(480, 540))
        self.ShowConfirmNewUserKeyCheckBox.Bind(wx.EVT_CHECKBOX, self.showConfirmNewUserKeyText)
        self.ConfirmNewUserKeyPasswordTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 540),
                                                              style=wx.TE_PASSWORD)
        self.NewUserKeyTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 480))
        self.NewUserKeyTextInput.Show(False)
        self.NewUserKeyPasswordTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 480),
                                                       style=wx.TE_PASSWORD)
        self.ShowNewUserKeyLabel = wx.StaticText(self.CreateUserPanel, label="Show Text", pos=(500, 480))
        self.NewUserNameLabel = wx.StaticText(self.CreateUserPanel, label="User Name", pos=(150, 420))
        self.SecurityQuestion3AnswerTextInput = wx.TextCtrl(self.CreateUserPanel, value="", pos=(220, 356))
        self.SecurityQuestion3ChoiceBox = wx.Choice(self.CreateUserPanel, choices=questions, pos=(220, 300))
        self.SecurityQuestion3ChoiceBox.SetSelection(0)
        self.SecurityQuestion2AnswerLabel = wx.StaticText(self.CreateUserPanel, label="Answer 2", pos=(150, 240))
        self.SecurityQuestion2Label = wx.StaticText(self.CreateUserPanel, label="Security Question 2", pos=(98, 180))
        self.SecurityQuestion1AnswerLabel = wx.StaticText(self.CreateUserPanel, label="Answer 1", pos=(150, 120))
        self.SecurityQuestion1ChoiceBox = wx.Choice(self.CreateUserPanel, choices=questions, pos=(220, 60))
        self.SecurityQuestion1ChoiceBox.SetSelection(0)
        self.SecurityQuestion1Label = wx.StaticText(self.CreateUserPanel, label="Security Question 1", pos=(98, 60))
        self.Show()

    def showNewUserKeyText(self, event):

        if self.ShowNewUserKeyCheckBox.GetValue() == True:
            self.NewUserKeyTextInput.SetValue(self.NewUserKeyPasswordTextInput.GetValue())
            self.NewUserKeyPasswordTextInput.Show(False)
            self.NewUserKeyTextInput.Show(True)
        elif self.ShowNewUserKeyCheckBox.GetValue() == False:
            self.NewUserKeyPasswordTextInput.SetValue(self.NewUserKeyTextInput.GetValue())
            self.NewUserKeyPasswordTextInput.Show(True)
            self.NewUserKeyTextInput.Show(False)

    def showConfirmNewUserKeyText(self, event):

        if self.ShowConfirmNewUserKeyCheckBox.GetValue() == True:
            self.ConfirmNewUserKeyTextInput.SetValue(self.ConfirmNewUserKeyPasswordTextInput.GetValue())
            self.ConfirmNewUserKeyPasswordTextInput.Show(False)
            self.ConfirmNewUserKeyTextInput.Show(True)
        elif self.ShowConfirmNewUserKeyCheckBox.GetValue() == False:
            self.ConfirmNewUserKeyPasswordTextInput.SetValue(self.ConfirmNewUserKeyTextInput.GetValue())
            self.ConfirmNewUserKeyPasswordTextInput.Show(True)
            self.ConfirmNewUserKeyTextInput.Show(False)

    def VerifyUniqueUserName(self, event):

        try:
            con = sqlite3.connect('reelz.db')
            cursor = con.cursor()
            sql = ''' SELECT * From Users Where userName = ? '''
            cursor.execute(sql, self.NewUserNameTextInput.GetValue())
            con.commit()
            con.close()

            print("this username already exsists please enter a diffrent usename and try again")
        except:
            print("user Name does not exsist proceed with creation")
            self.addNewUser()

    def addNewUser(self):
        username = self.NewUserNameTextInput.GetValue()
        userHash = self.hashNewUserPassword()
        #  function will have to be made to convert found index / selection to text
        securityQuestion1Selection = self.ConvertQuestionSelectionToText(self.SecurityQuestion1ChoiceBox)
        securityQuestion2Selection = self.ConvertQuestionSelectionToText(self.SecurityQuestion2ChoiceBox)
        securityQuestion3Selection = self.ConvertQuestionSelectionToText(self.SecurityQuestion3ChoiceBox)
        answer1 = self.HashSecurityQuestionAnswers(self.SecurityQuestion1AnswerTextInput.GetValue())
        answer2 = self.HashSecurityQuestionAnswers(self.SecurityQuestion2AnswerTextInput.GetValue())
        answer3 = self.HashSecurityQuestionAnswers(self.SecurityQuestion3AnswerTextInput.GetValue())
        newUser = [
            username, userHash, securityQuestion1Selection, answer1, securityQuestion2Selection, answer2,
            securityQuestion3Selection,
            answer3

        ]

        try:
            con = sqlite3.connect('Reelz.db')
            cursor = con.cursor()
            sql = '''INSERT INTO  Users(userName,hash,securityQuestion1,securityQuestion1Answer,
            securityQuestion2, securityQuestion2Answer, securityQuestion3,securityQuestion3Answer) VALUES (?,
                      ?,?,?,?,?,?,?) '''
            cursor.execute(sql, newUser)
            con.commit()
            con.close()
            print(" User sucessfully added")
        except:
            print(" there was a problem adding the User to the database")

    def hashNewUserPassword(self):

        userKey = self.NewUserKeyTextInput.GetValue()
        userKeyHash = None

        try:

            userKeyHash = hasher.hash(userKey)
            print(userKeyHash)
            hasher.verify(userKeyHash, userKey)
            print(hasher.verify(userKeyHash, userKey))
            print(" user key sucessfully hashed")
        except:
            print("we have a problem with the password hashing")

        return userKeyHash

    def HashSecurityQuestionAnswers(self, anwser):

        anwserHash = None

        try:
            anwserHash = hasher.hash(anwser)
            print(anwserHash)
            hasher.verify(anwserHash, anwser)
            print(hasher.verify(anwserHash, anwser))
            print(" security question anwser sucessfuly hashed")
        except:
            print("we had a problem hashing 1 or more security question")

        return anwserHash

    def ConvertQuestionSelectionToText(self, selectedQuestionIndex):
        QuestionIndex = selectedQuestionIndex.GetSelection()
        ConvertedQuestion = selectedQuestionIndex.GetString(QuestionIndex)
        return ConvertedQuestion


if __name__ == '__main__':
    app = wx.App()
    frame = CreateUserFrame(title="title happy")
    frame.Show()
    app.MainLoop()

Thank you for your time and any help.

Thomas Gustafosn

I'm sorry, but I can't deduce what's going wrong from such a huge source dump, please provide an
Short, Self Contained, Correct, Example.

The hash changes on every hashing, because it's using a random salt that becomes part of the hash.

It might also be a good idea to stop catching all exceptions and printing an error and look at the error instead – who knows what's going wrong.

I did actually figure out what the problem was it was that I was accessing the wrong input field.
(in the create user class file)
I have a text control that has a password mask and an text control underneath it that does not so the user can click the checkbox to show the password and I was retrieving from the non masked control which is only set to the same text when the user checks the checkbox. I also had to implement the same feature on the login page.

Thank you for your help