为什么我在使用相同的密钥时会得到加密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:UsersJamesDocumentspasswordsvenvScriptspython.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:UsersJamesDocumentspasswordsvenvlibsite-packagescryptographyfernet.py", line 119, in _verify_signature
h.verify(data[-32:])
File "C:UsersJamesDocumentspasswordsvenvlibsite-packagescryptographyhazmatprimitiveshmac.py", line 74, in verify
ctx.verify(signature)
File "C:UsersJamesDocumentspasswordsvenvlibsite-packagescryptographyhazmatbackendsopensslhmac.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:UsersJamesDocumentspasswordsvenvlibsite-packagescryptographyfernet.py", line 80, in decrypt
return self._decrypt_data(data, timestamp, time_info)
File "C:UsersJamesDocumentspasswordsvenvlibsite-packagescryptographyfernet.py", line 137, in _decrypt_data
self._verify_signature(data)
File "C:UsersJamesDocumentspasswordsvenvlibsite-packagescryptographyfernet.py", line 121, in _verify_signature
raise InvalidToken
cryptography.fernet.InvalidToken
Process finished with exit code 1

问题是,您为所选帐户密码输入用户,然后附加拆分器和随机生成的密码,然后添加'/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')

最新更新