微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我在使用相同的密钥时会收到密码学 fernet InvalidToken

如何解决为什么我在使用相同的密钥时会收到密码学 fernet InvalidToken

你好,我正在制作一个密码管理器,我想加密密码文件,所以我生成并创建了第一个密码,当我读取它并解密时它会读取它。然后在创建另一个密码时它会创建它,但在解密时会引发错误。据我所知,我使用的是相同的密钥。 代码如下:

#imports
import random,string,os,sys
from cryptography.fernet import Fernet
import bcrypt

if os.path.isfile('salt.txt'):
    #Gets the salt
    with open('salt.txt','rb') as saltfile:
        salt = saltfile.read()

else:
    with open('salt.txt','wb')as saltfile:
        salt = bcrypt.gensalt()
        saltfile.write(salt)
        saltfile.close()

#Hashes the item
def hashPass(item):
    global passwordOut
    hashed = bcrypt.hashpw(item,salt)
    passwordOut = hashed
    return passwordOut

#Password Generator
def setPassword(length=30,char=string.ascii_letters+string.digits+string.punctuation):
    global generatedPassword
    generatedPassword= ''.join(random.choice(char) for x in range(length))
    return generatedPassword

if os.path.isfile('mykey.key') == True:
    #Opens the key
    with open('mykey.key','rb') as mykey:
        print('True')
        key = mykey.read()
        f = Fernet(key)
        mykey.close()
elif os.path.isfile('mykey.key')== False:
    print('False')
    # Generates a kay
    key = Fernet.generate_key()
    # Writes a new key
    with open('mykey.key','wb') as mykey:
        mykey.write(key)
        f = Fernet(key)
        mykey.close()

#Sets the key

#Stating initalization
print("Hello and welcome to your password manager!")

while True:
    #If there is a user file
    if os.path.isfile('user.txt'):
        #Read the user file
        with open('user.txt','rb') as user_file:
            file = user_file.read()

        #Gets the inputs
        getUser = input("Enter your username ").encode('utf-8')
        getpass = input('Enter your password: ').encode('utf-8')

        #Hashes the inputs through the hashing funcion
        hashPass(item=getUser)
        usr = passwordOut
        hashPass(item=getpass)
        passw = passwordOut

        #If the users hashed input is the same in the users file it carries on with the procedure
        if usr in file and passw in file:
            while True:
                print("""Pick from the list of what you want to do:
                1. Generate a new password
                2. See passwords
                3. Quit""")

                usrinput = int(input('Enter a number from the menu: '))

                if usrinput == 1:
                    print("\nGenerating password...")
                    setPassword()
                    usrinput = input("What is the password for: ")
                    splitter = ': '
                    #
                    if os.path.isfile('passwordenc.txt'):
                        with open('passwordenc.txt','ab')as password_file:
                            var = usrinput + splitter + generatedPassword + '\n'
                            encrypted = f.encrypt(bytes(var.encode('utf-8')))
                            password_file.write(encrypted)
                            print("Your new password for: "+usrinput)
                            print("And the password is: "+generatedPassword)
                            password_file.close()
                    else:
                        with open('passwordenc.txt','wb')as password_file:
                            var = usrinput + splitter + generatedPassword + '\n'
                            encrypted = f.encrypt(bytes(var.encode('utf-8')))
                            password_file.write(encrypted)
                            print("Your new password for: " + usrinput)
                            print("And the password is: " + generatedPassword)
                            password_file.close()

                if usrinput == 2:
                    if os.path.isfile('passwordenc.txt'):
                        with open('passwordenc.txt','rb') as password_file:
                            read = password_file.read()
                            decrypt = f.decrypt(read)
                            print(decrypt)
                            password_file.close()

                    else:
                        print('File not found! Need to create a new file.')

                if usrinput == 3:
                    quit()


        #If not the same it loops back around
        else:
            print("\nUser not found!\n")


    #If there is no file:
    else:
        #Gets a user input
        username = input('Enter a username: ').encode('utf-8')
        password = input('Enter a password,cannot be changed! ').encode('utf-8')

        #Hashes the user input
        hashPass(item=username)
        usr = passwordOut
        hashPass(item=password)
        passw = passwordOut

        #Writes the user input
        with open('user.txt','wb') as user:
            user.write(usr)
            user.write(passw)
        print('\nUser has been created!\n')

这是终端代码

C:\Users\James\Documents\passwords\venv\Scripts\python.exe C:/Users/James/Documents/passwords/main.py
True
Hello and welcome to your password manager!
Enter your username james
Enter your password: Kaits_1204
Pick from the list of what you want to do:
                1. Generate a new password
                2. See passwords
                3. Quit
Enter a number from the menu: 2
Traceback (most recent call last):
  File "C:\Users\James\Documents\passwords\venv\lib\site-packages\cryptography\fernet.py",line 119,in _verify_signature
    h.verify(data[-32:])
  File "C:\Users\James\Documents\passwords\venv\lib\site-packages\cryptography\hazmat\primitives\hmac.py",line 74,in verify
    ctx.verify(signature)
  File "C:\Users\James\Documents\passwords\venv\lib\site-packages\cryptography\hazmat\backends\openssl\hmac.py",line 75,in verify
    raise InvalidSignature("Signature did not match digest.")
cryptography.exceptions.InvalidSignature: Signature did not match digest.

During handling of the above exception,another exception occurred:

Traceback (most recent call last):
  File "C:/Users/James/Documents/passwords/main.py",line 106,in <module>
    decrypt = f.decrypt(read)
  File "C:\Users\James\Documents\passwords\venv\lib\site-packages\cryptography\fernet.py",line 80,in decrypt
    return self._decrypt_data(data,timestamp,time_info)
  File "C:\Users\James\Documents\passwords\venv\lib\site-packages\cryptography\fernet.py",line 137,in _decrypt_data
    self._verify_signature(data)
  File "C:\Users\James\Documents\passwords\venv\lib\site-packages\cryptography\fernet.py",line 121,in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken

Process finished with exit code 1

解决方法

问题是您输入用户选择的帐户密码,然后附加拆分器和随机生成的密码,然后'/n'。之后,您使用 var 加密此 fernet。此方法将用于查看您的第一个密码,因为您使用第一个密码读取并解密整个文件,但不能使用多个加密密码,因为每个 var 加密都是唯一的(具有不同的 IV),这意味着要解密所有您需要一种方法来表示加密密码的结束和另一个加密密码的开始,以便您将正确的密文以正确的边距传递给 ferent。这可以通过在每次加密写入密码文件后简单地添加 --END OF PASSWORD-- 来完成。然后在读取密码时,您可以在这些边距上拆分 pass 文件并将结果传递给 fernet。

注意:不要将此代码用作您的密码管理器,因为尽管您对密码进行了加密,但您的主密码 mykey.key 未加密,这使得这完全没有用。

import random,string,os,sys
from cryptography.fernet import Fernet
import bcrypt

if os.path.isfile('salt.txt'):
    #Gets the salt
    with open('salt.txt','rb') as saltfile:
        salt = saltfile.read()

else:
    with open('salt.txt','wb')as saltfile:
        salt = bcrypt.gensalt()
        saltfile.write(salt)
        #saltfile.close()       # You dont need to close

#Hashes the item
def hashPass(item):
    global passwordOut
    hashed = bcrypt.hashpw(item,salt)
    passwordOut = hashed
#    return passwordOut

# Random Password Generator 
def setPassword(length=30,char=string.ascii_letters+string.digits+string.punctuation):
    global generatedPassword
    generatedPassword= ''.join(random.choice(char) for x in range(length))
    return generatedPassword

if os.path.isfile('mykey.key') == True:
    #Opens the key
    with open('mykey.key','rb') as mykey:
        print('True')
        key = mykey.read()
        f = Fernet(key)

elif os.path.isfile('mykey.key')== False:
    print('False')
    # Generates a kay
    key = Fernet.generate_key()
    # Writes a new key
    with open('mykey.key','wb') as mykey:
        mykey.write(key)
        f = Fernet(key)
        #mykey.close()          # with doesnt need file to be closed

#Sets the key

#Stating initalization
print("Hello and welcome to your password manager!")

while True:
    #If there is a user file
    if os.path.isfile('user.txt'):
        #Read the user file
        with open('user.txt','rb') as user_file:
            file = user_file.read()
            print("File ",file)

        #Gets the inputs
        getUser = input("Enter your username ").encode('utf-8')
        getPass = input('Enter your password: ').encode('utf-8')

        #Hashes the inputs through the hashing funcion
        hashPass(item=getUser)
        usr = passwordOut
        hashPass(item=getPass)
        passw = passwordOut

        #If the users hashed input is the same in the users file it carries on with the procedure
        if usr in file and passw in file:
            while True:
                print("""Pick from the list of what you want to do:
                1. Generate a new password
                2. See passwords
                3. Quit""")

                usrinput = int(input('Enter a number from the menu: '))

                if usrinput == 1:
                    print("\nGenerating password...")
                    setPassword()
                    usrinput = input("What is the password for: ")
                    splitter = ': '
                    #
                    if os.path.isfile('passwordenc.txt'):
                        with open('passwordenc.txt','ab')as password_file:
                            var = usrinput + splitter + generatedPassword + '\n'
                            encrypted = f.encrypt(bytes(var.encode('utf-8')))
                            password_file.write(encrypted)
                            password_file.write(b"--END OF PASSWORD--")

                            print("Your new password for: "+usrinput)
                            print("And the password is: "+generatedPassword)
                            

                    else:
                        with open('passwordenc.txt','wb')as password_file:
                            var = usrinput + splitter + generatedPassword + '\n'
                            encrypted = f.encrypt(bytes(var.encode('utf-8')))                    
                            password_file.write(encrypted)
                            password_file.write(b"--END OF PASSWORD--")

                            print("Your new password for: " + usrinput)
                            print("And the password is: " + generatedPassword)


                if usrinput == 2:
                    if os.path.isfile('passwordenc.txt'):                    
                        with open('passwordenc.txt','r') as password_file:
                            whole_file = password_file.read()
                            password_list = whole_file.split("--END OF PASSWORD--")                        
                            for password in password_list:
                                if password:
                                    decrypt = f.decrypt(bytes(password,encoding="utf-8"))
                                    print("Decrypted pass: ",decrypt)                

                    else:
                        print('File not found! Need to create a new file.')

                if usrinput == 3:
                    quit()


        #If not the same it loops back around
        else:
            print("\nUser not found!\n")


    #If there is no file:
    else:
        #Gets a user input
        username = input('Enter a username: ').encode('utf-8')
        password = input('Enter a password,cannot be changed! ').encode('utf-8')

        #Hashes the user input
        hashPass(item=username)
        usr = passwordOut
        hashPass(item=password)
        passw = passwordOut

        #Writes the user input
        with open('user.txt','wb') as user:
            user.write(usr)
            user.write(passw)
        print('\nUser has been created!\n')

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。