为什么使用同一密钥时会获得加密fernet InvalidToken

2024-04-24 11:21:39 发布

您现在位置:Python中文网/ 问答频道 /正文

您好,我正在制作一个密码管理器,我想对密码文件进行加密,所以我生成并创建了第一个密码,当我读取并解密它时,就会读取它。然后,当创建另一个密码时,它会创建密码,但当解密密码时会抛出一个错误。从我所看到的,我使用的是同一把钥匙。 代码如下:

#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


Tags: thekeyintxtinputifwithpassword
1条回答
网友
1楼 · 发布于 2024-04-24 11:21:39

问题是,您需要用户输入所选帐户密码,然后附加拆分器和随机生成的密码,然后'/n'。然后,使用fernet对该var进行加密。此方法将用于查看您的第一个密码,因为您使用第一个密码读取并解密整个文件,但不使用多个加密密码,因为每个var加密都是唯一的(具有不同的IV)这意味着要解密所有密码,您需要一种方法来发出加密密码结束和另一个加密密码开始的信号,以便将具有正确边距的正确密文传递给ferent。这可以通过简单地在每次加密写入密码文件后添加 END OF PASSWORD 来实现。然后,在读取密码的过程中,您可以在这些页边距上拆分密码文件,并将结果传递给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')

相关问题 更多 >