-1
backend = default_backend()
salt = b'2444'

kdf = PBKDF2HMAC(
    algorithm=hashes.SHA256(),
    length=32,
    salt=salt,              
    iterations=100000,
    backend=backend
)

This is the kdf setup.

    def getMasterPassword():
            checkHashedPassword = hashPassword(txt.get().encode('utf-8'))
            global encryptionKey
            encryptionKey = base64.urlsafe_b64encode(kdf.derive(txt.get().encode()))
            cursor.execute('SELECT * FROM masterpassword WHERE id = 1 AND password = ?', [(checkHashedPassword)])
            return cursor.fetchall()

    def checkPassword():
        password = getMasterPassword()

        if password:
            vaultScreen()
        else:
            txt.delete(0, 'end')

This is my hash algorithm

in derive
    raise AlreadyFinalized("PBKDF2 instances can only be used once.")
cryptography.exceptions.AlreadyFinalized: PBKDF2 instances can only be used once.

This is the error I am getting when input a wrong password and then try to re-enter it.
Libraries used:

  • sqlite
  • hashlib
  • tkinter
  • customtkinter
  • functools
  • uuid
  • pyperclip
  • base64
  • cryptography
  • 2 Answers2

    0

    this should work correctly. basically what i found out is that you can't have "encryptionKey = base64.urlsafe_b64encode(kdf.derive(txt.get().encode())" being ran more than once so you basically need to put it somewhere that it can only be accessed once and in this instance it's only when your password is correct. creating a logout system would be difficult to do but not impossible.

     def getMasterPassword():
                global Pss
                Pss = txt.get().encode()
                checkHashedPassword = hashPassword(txt.get().encode('utf-8'))
                
                cursor.execute('SELECT * FROM masterpassword WHERE id = 1 AND password = ?', [(checkHashedPassword)])
                return cursor.fetchall()
    
        def checkPassword():
            password = getMasterPassword()
    
            if password:
                vaultScreen()
                global encryptionKey
                global Pss
                encryptionKey = base64.urlsafe_b64encode(kdf.derive(Pss))
            else:
                txt.delete(0, 'end')
    
    0

    Instead of using the same "PBKDF2" instance, you can change "kdf" variable into a function that initializes a new "PBKDF2" instance for every login attempt:

    def kdf():
        return PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=backend)
    

    Then your "getMasterPassword" function should be changed to:

    def getMasterPassword():
        checkHashedPassword = hashPassword(txt.get().encode('utf-8'))
        global encryptionKey
        encryptionKey = base64.urlsafe_b64encode(kdf().derive(txt.get().encode()))
        cursor.execute('SELECT * FROM masterpassword WHERE id = 1 AND password = ?', [(checkHashedPassword)])
        return cursor.fetchall()
    

    Not sure if this approach has any cons that you should be aware of, but it should work as intended.

    From3
    • 1
    • 2