Hello so I am making a password manager and I want to encrypt the password file, so I generate and create the first password and when I read it and decrypt it reads it. And then when making another password it creates it but then when decrypting it throws an error. From what I can see I am using the same key. Here is the code:
#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')
Here is the terminal code:
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
The problem is that you take input of user for chosen account password then you append splitter and random generated password then '/n'
. After that you encrypt this var
using fernet
. This method will work to view your first password since with first password you read and decrypt whole file but not with multiple encrypted passwords since each var
encryption is unique (having different IV
) which means that to decrypt all the passwords you will need a way to signal the end of an encrypted password and beginning of another encrypted password so that you pass to ferent
the correct ciphertext with correct margins. This can be done by simply adding --END OF PASSWORD--
after each encryption write to password file. Then during reading of passwords you can just split pass file on these margins and pass result to fernet.
NOTE: dont use this code as your password manager since although you encrypt your passwords you are leaving your master password in mykey.key
unencrypted which makes this totally useless.
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')