I am geting an error when trying to check a password using the bcrypt library. The issue seems to be that the hashed variable should be a plain string without "quotation marks". I've attempted to remove the quotation marks multiple times but the error persists. I am seeking assistance in removing the quotation marks from the "hashed" variable in order to make the bcrypt checkpw function work properly.
#----------------------------------------------------------------
#----------------------------------------------------------------
# import module to dencrypt password
#----------------------------------------------------------------
#----------------------------------------------------------------
import bcrypt
def Log_in():
# Print separator line
print("-"*70)
# Prompt user for email or username and password
msg0 = "Enter your username or your email address"
msg1 = "Enter your password"
user_input = input(f"{msg0:45}| ")
user_pasword = input(f"{msg1:45}| ")
print("-"*70)
# Open and read the text file where the user database is stored
db = open("database.txt",'r')
contant = db.readlines()
email_list = []
username_list = []
password_list=[]
# Check if there's content in the database
if contant == None:
pass
else:
# Split each line of the content by '| ' and append the parts to their corresponding lists
for i in contant:
a, b, c, d = i.split("| ")
email_list.append(a.strip())
username_list.append(b.strip())
password_list.append(d.strip())
# Close the file
db.close()
# Check if the entered email or username exists in the email_list or username_list
if user_input in username_list or user_input in email_list:
x = None
y = None
# Try to get the index of the entered email or username in the email_list and username_list
try:
x = username_list.index(user_input)
except:
pass
try:
y = email_list.index(user_input)
except:
pass
if x != None and y == None:
# If the entered username exists in the username_list
# Strip the 'b' character, encode the string to utf-8 and compare it with the entered password
hashed = password_list[x].strip('b')
# hashed = hashed.replace("'","")
hashed = hashed.encode('utf-8')
if bcrypt.checkpw(user_pasword.encode('utf-8'), hashed):
print("Welcome")
else:
print("incorrect password")
Log_in()
elif y != None or x == None:
# If the entered email exists in the email_list
# Remove the double quotes and compare it with the entered password
hashed = password_list[y][:-1]
hashed = hashed.replace('"','')
# hashed1 = hashed.replace(b"\n", b"")
if bcrypt.checkpw((user_pasword.encode("utf-8")),hashed): #error happening here
print("Welcome")
else:
print("incorrect password")
Log_in()
else:
print("incorrect password")
Log_in()
else:
# If the entered email or username doesn't exist in the email_list or username_list
print("This username or the email does not exist")
Log_in()
# main function
if __name__ == "__main__":
Log_in()
Related
I'm new to python, an I decided to write a simple password manager to learn. I'm having trouble retrieving one of the values out of the dictionary.
The function add_password write a key with 2 values (user, and password (encrypted))
And the function get_password read the key and supposed to get the values.
I can't get it to pull the value of user.
I have tried multiple methods, but so far no luck.
https://github.com/ae3erdion/Password_Manager/blob/main/main.py
import base64
import os
import string
import random
from unittest import TestCase
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
characters = list(string.ascii_letters + string.digits + "!##$%^&*()")
site = ""
user = ""
password = ""
password_file = {}
encrypted = ""
# Generate key for encryption
def generate_key():
password = input ("Enter password: ")
password = bytes(password, 'utf-8')
salt = b'\xceN\x01s\xabE\x15\x02\xd9pz(1\t\xbc4'
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=390000,
)
global key
key = base64.urlsafe_b64encode(kdf.derive(password))
# Check for the encryption key hash file exists and validate if the key is the same
if os.path.exists('password.hash'):
with open('password.hash', 'rb') as f:
key_validation = f.read()
if key_validation == key:
print("What would you like to do: ")
menu()
else:
print("Wrong password ")
exit
# If key hash file doesnt exist it create the file and write the encryption key hash to it
else:
with open('password.hash', 'wb') as f:
f.write(key)
with open('password.encode', 'wb') as f:
print("What would you like to do: ")
menu()
# Randon password generator
def generate_password():
length = int(16)
random.shuffle(characters)
random_password = []
for i in range(length):
random_password.append(random.choice(characters))
random.shuffle(random_password)
random_password = ("".join(random_password))
print(random_password)
# Write a new password to the pasword file
def add_password(site, user, password_site):
password_file[site] = password_site
with open('password.encode', 'a+') as f:
encrypted = Fernet(key).encrypt(password_site.encode())
f.write(site + " " + user + ":" + encrypted.decode() + "\n")
# Read password file and get the password
def get_password(site):
with open('password.encode', 'r') as f:
for line in f:
site, encrypted = line. split (":")
password_file[site] = Fernet(key).decrypt(encrypted.encode()).decode()
return password_file[site]
# Check for all files.
def main():
if os.path.exists('password.hash') & os.path.exists('password.encode'):
print ("Welcome Back!")
generate_key()
else:
print ("""
Welcome!
Create password""")
generate_key()
# Menu of options
def menu():
print("""
(1) Generate random password
(2) Add new password
(3) Get login information
(q) Quit""")
done = False
while not done:
choice = input("Enter choice: ")
if choice == "1":
generate_password()
elif choice == "2":
site = input("Enter the site: ")
user = input("Enter User: ")
password = input("Enter the password: ")
add_password(site, user, password)
elif choice == "3":
site = input("Enter site: ")
print(f"Your login information for {site} is ({get_password(site)})")
elif choice == "q":
done = True
print("Bye!")
else:
print("Invalid Choice")
if __name__== "__main__":
main()
If you change you get_password function to:
def get_password(site):
with open('password.encode', 'r') as f:
for line in f:
site, encrypted = line.split (":")
site, user = site.split()
password_file[site] = (user, Fernet(key).decrypt(encrypted.encode()).decode())
return password_file[site]
and change option 3 in your menu function
elif choice == "3":
site = input("Enter site: ")
user, passwd = get_password(site)
print(f"Your login information for {user}#{site} is ({passwd})")
You will still want to implement some error checking but that should will at least get you started.
import json
def write_json(data, file='users.json'):
with open(file, 'w') as f:
json.dump(data, f, indent=4)
while True:
user = {'name':[], 'password':[]}
choice = int(input('1) Register, 2) Login\n>> '))
if choice == 1:
username = input('Enter username: ')
password = input('Enter password: ')
user['name'] = username
user['password'] = password
print('Registered successfully')
with open('users.json') as json_file:
data = json.load(json_file)
users = data['users']
for user in users:
if user['name'] == username:
print(f'User "{username}" already exists')
break
new_user = user
users.append(new_user)
write_json(data)
if choice == 2:
username = input('Enter username: ')
password = input('Enter password: ')
with open('users.json', 'r') as f:
data = json.load(f)
for user in data['users']:
if user['name'] == username and user['password'] == password:
print('Logged in succesfully')
I am trying to make a simple login/register system, but when the user registers for the 2nd time, its gets overridden by the 1st key/value every time, I tried user.clear() but it doesnt seem to have an effect
The issue is that you are using a single dict item for all your users. The way you've set it up only allows for one user to exist.
You need to restructure your dict. You could do a list of dict items, but I would suggest using the username as the key in your dict. Since usernames are supposed to be unique, this makes sense IMHO.
In case you want to use the simpler list of dict items metioned above, you would structure it as follows:
[
{'Edo': 'mypassword'},
{'Iso': 'yourpassword'}
]
I've added some comments on the adjusted code below...
import json
def write_json(data, file="users.json"):
with open(file, "w") as outfile:
json.dump(data, outfile, indent=4)
def load_json(file="users.json"):
# try block in case file doesn't exist
try:
with open(file) as infile:
result = json.load(infile)
return result
except Exception as e:
# just printing out the error
print(e)
# should only be file not found error
# returning an empty dict
return {}
while True:
# you need to load before actually doing anything.
# if you don't you might overwrite the file
userlist = load_json()
# newlines for each option
choice = int(input("1) Register\n2) Login\n>> "))
if choice == 1:
username = input("Enter username: ")
# check if user already exists before requesting password
# since usernames are supposed to be unique, you can just
# create a dict with the key being username.
# you could use the value directly for password, but
# if you need to store more values for a user, I advice
# you use another dict as the value.
if username in userlist:
print(f"User {username} already exists")
# do some other magic here to handle this scenario
# continue makes the while loop go to the next iteration
continue
password = input("Enter password: ")
userlist[username] = {"password": password, "someotheruserdate": "dunno?"}
write_json(userlist)
# only print the success **after** you've actually
# completed all relevant logic.
print("Registered successfully")
# change this to elif instead of a second if statement
elif choice == 2:
username = input("Enter username: ")
password = input("Enter password: ")
if username in userlist and userlist[username]["password"] == password:
print("Logged in succesfully")
else:
# handle wrong username/password
# here you need to check after getting both username&password
print("Incorrect username/password combination")
I am making a user system. I need to store the usernames and passwords in a file.
Case 1: If existing user=
I need to read the username and password to check existing user.
I need to check if the passwords match from the keyed in value and from the dictionary value.
Case 2 : If new user=
I need to check if the username already exist in the database.
If not then, i need to append the username and password in existing file without overwriting.
The problem here, i have utilised json here but it seems to overwrite the existing dict.
I have tried writing to a simple text file and i encounter problem in case when reading the file and also when i check if username exists in case 2.
# Login System Management
import json
class LoginSystem:
def __init__(self): # Opening and reading the registered users json.file
self.users = json.load(open("Users.json"))
self.login_screen()
def login_screen(self): # Log on screen to verify new or old user.
while True:
main_log = input("Are you new user?\n[Y]es or [N]o: ")
if main_log == "Y":
self.new_user()
break
elif main_log == "N":
self.old_user()
break
else:
print("Invalid answer.\n")
def old_user(self): # Log in screen if old user.
while True:
user_id = input("Please enter your user id: ")
user_password = input("Please enter your password: ")
if len(user_id) <= 64 and len(user_password) <= 64 and self.check_system(user_id, user_password):
print("Logging In")
break
else:
print("Wrong password or username!\n")
def check_system(self, name, password): # Checking system to verify old user id and password.
data = self.users
try:
expected_password = data[name]
except KeyError:
return False
if password != expected_password:
return False
return True
def new_user(self): # Log in screen if new user.
while True:
print("\nMax Length is 64 chars.")
reg_id = input("Register your username: ")
reg_password = input("Key in password: ")
if len(reg_id) <= 64 and len(reg_password) <= 64:
if reg_id not in self.users:
print("Loading.....")
self.update_database(reg_id, reg_password)
print("Registered Successfully.")
break
else:
print("User already registered!\n")
self.old_user()
break
else:
print("Error. Max Length is 64 chars.\n")
def update_database(self, new_user_name, new_user_password): # Writing new username and password to json.file
new_username = new_user_name
new_password = new_user_password
field = [new_username, new_password]
with open("Users.json", "w") as f:
json.dump(field, f)
check = LoginSystem()
The problem is that you are opening the csv file in "write" mode. This mode replaces what you have written in the database so far with the new line. Use "append" instead.
with open("Users.json", "a") as f:
I had figure out the answer. If anyone wants to refer you can follow.
First, I have created a csv file with row of line username,password and save it in the same directory.
The rest as follows the code.
# Login System Management import csv import time
class LoginSystem:
def __init__(self): # Opening
self.login_screen()
def login_screen(self): # Log on screen to verify new or old user.
while True:
main_log = input("Are you new user?\n[Y]es or [N]o: ")
if main_log == "Y":
self.new_user()
break
elif main_log == "N":
self.old_user()
break
else:
print("Invalid answer.\n")
def old_user(self): # Log in screen if old user.
while True:
user_id = input("\nPlease enter your user id: ")
user_password = input("Please enter your password: ")
if len(user_id) <= 64 and len(user_password) <= 64 and self.read_database(user_id, user_password):
print("Successful")
break
else:
print("Wrong password or username!\n")
def new_user(self): # Log in screen if new user.
print("\nMax Length is 64 chars.")
reg_id = input("Register your username: ")
if self.check_database(reg_id) is True:
while True:
reg_password = input("Key in password: ")
if len(reg_id) <= 64 and len(reg_password) <= 64:
print("Loading.....")
time.sleep(2)
self.update_database(reg_id, reg_password)
print("Registered Successfully.")
break
else:
print("Error. Max Length is 64 chars.\n")
else:
print("User Already Exists.\n")
self.old_user()
def read_database(self, name, password): # Checking if password match to username
with open("Users.csv", "r") as f:
reader = csv.reader(f)
user_list = {}
for row in reader:
user_list[row[0]] = row[1]
try:
expected_password = user_list[name]
if password == expected_password:
print("Logging In")
time.sleep(2)
return True
except KeyError:
return False
if password != expected_password:
return False
def check_database(self, new_name): # Checking if new id exists in user database
with open("Users.csv", "r") as f:
reader = csv.reader(f)
user_list = {}
for row in reader:
user_list[row[0]] = row[1]
if new_name in user_list.keys():
return False
elif new_name not in user_list.keys():
return True
def update_database(self, new_user_name, new_user_password): # Writing new username and password to file
with open("Users.csv", "a", newline="\n") as f: # appends the new username and password to new row of line
writer = csv.writer(f)
writer.writerow([new_user_name, new_user_password])
check = LoginSystem()
**This is a practice application
I have a text file containing a id & a password. Each pair is on separate lines like so:
P1 dogs
P2 tree
I then have 2 functions to allow the user the add another id/password or update the password by selecting an ID then the new password. (I have removed the save functionality so I don't create loads of pairs when testing)
The question is how would I write a check function so that when the user is creating a new pair.. it checks if the id/password already exists. Then on the update password function, it only checks if the password exists?
My code so far:
#Keyword check
def used_before_check(keyword, fname):
for line in open(fname, 'r'):
login_info = line.split()
username_found = False
for line in login_info:
if keyword in line:
username_found == True
if username_found == True:
return True
else:
return False
# New password function
def new_password():
print("\nCreate a new password")
new_id_input = input("Please give your new password an ID: ")
new_password_input = input("Please enter your new password: ")
print("ID in use?", used_before_check(new_id_input, txt_file))
print("Password in use?", used_before_check(new_password_input, txt_file))
#Change password function
def change_password():
print("\nChange password")
id_input = input("Enter the ID of the password you'd like to change: ")
password_input = input("Now enter the new password: ")
print("password_input",used_before_check(password_input, txt_file))
The easiest way would be to use JSON:
import json
import os
def new_password(user, password, password_dict={}):
if user in password_dict:
password_dict[user] = password # change password
else:
password_dict[user] = password # new password
return password_dict
def read_passwords(filename):
if not os._exists(filename):
return {}
with open(filename, 'r') as f:
s = f.read()
return json.loads(s)
password_filename = 'my_passwords.json'
password_dict = read_passwords(password_filename)
user = ''
while not user == 'q':
user = input('user:')
password = input('new password:')
if user != 'q':
password_dict = new_password(user, password, password_dict)
s = json.dumps(password_dict)
with open(password_filename, 'w') as f:
f.write(s)
Not that I have included a seemingly unnecessary if clause in new_password. This is just for you that you can easily enter your own code what you want to do (maybe different) in each case.
Create a function to store your usernames/passwords in a dictionary, then you can easily check it for existing usernames/passwords
To store in dictionary:
def process_file(fname):
username_pw_dict = {}
for line in open(fname, 'r'):
login_info = line.rstrip().split()
username = login_info[0]
pw = login_info[1]
username_pw_dict[username] = pw
return username_pw_dict
username_pw_dict = process_file(fname)
Then you can check for existing usernames or passwords like this:
if new_username in username_pw_dict:
print("username already exists")
if new_pw in username_pw_dict.values():
print("password already exists")
When you are reading the file, make a dictionary with all the IDs as its keys.
In next step, reverse the dictionary key-value pair so all its values (i.e all passwords) become its keys.
Finally, when you enter a new ID and password, just check those dictionaries to know if they already exist. You may refer to this below code:
dict_ids = {1 : "one", 2:"two", 3:"three"};
dict_pwds = {}
for key, value in dict_ids.items():
for string in value:
dict_pwds[value] = key;
print "dict_ids ", dict_ids;
print "dict_pwds ", dict_pwds;
if 'myid' in dict_ids.keys():
print "ID exist! "
else:
print "New ID"
if 'mypwd' in dict_pwds.keys():
print "Password exist! "
else:
print "New Password"
I am having issues with the current program that I am trying to write. I don't understand why it keeps saying this or why.
Also can this code be extended to cover IP logging and making sure multiple users can be logged in on the same IP in theory?
Here is the code:
import hashlib
import time
#cPickle is faster then pickle but not available in all python releases
#thats why i used a try/accept there
try: import cPickle as cp
#load the database if it exist, if not it create one
try:
f =(r"C:\Users\Owner\Desktop\python\database.data")
data = cp.load(f)
except IOError:
data = {}
#A simple function made to make data dumping easy
def easyDump(data_):
f = file(r"C:\Users\Owner\Desktop\python\database.data", "w")
cp.dump(data_, f)
f.close()
#Get's the date (We'll use this as the custom salt)
def getData():
return str(time.strftime("%d-%m-%Y"))
#A function which accepts two parameters, password and date.
#The date is the custom salt. It returns the sha512 hash excetpyion
def salt(password, date):
salted = hasglib.sha512(password + str(data)).hexdigest()
retun str(salted)
menu = """"
1.Login
2.Register
3.Exit
"""
while True:
print menu
choice = int(raw_input("Your choice please: "))
if choice ==1:
username = raw_input("Enter your username please: ")
password = raw.input("Enter your authentication code please: ")
#if the username is found on the database
if data.has_key(username):
#date is equal to our secured stored data
date = date[username][1]
#check of the given password + date is equal to what is stored on the database
#password
if salt(password, date) == date[username][0]:
print"Welcome %s!" % username
else:
print "Incorrect password"
else:
print "user %s not found, please register!" % username
elif choice == 2:
username = raw_input("Please enter yout username: !")
password = raw_input("Please enter your password: !")
#if username exists in the system already then the name is taken
if data.has_key(username):
print "user %s already registered, please put in another % username
else:
#in order words data = {username: hash, date}
data[username] = [salt(password, getData()), get Data()]
easyDump(data)
print "user %s successfully registereed!" %username
elif choice == 3:
print "goodbye!"
break
else:
print "invaid input or commands"
This code:
try: import cPickle as cp
is not followed by an except ... hence the syntax error
Your code contains many indenting, syntax errors and spelling mistakes. The following fixes these to allow it to at least run:
import hashlib
import time
#cPickle is faster then pickle but not available in all Python releases
#That is why I used a try/accept there
try:
import cPickle as cp
except:
import pickle as cp
#load the database if it exist, if not it create one
try:
f = open(r"C:\Users\Owner\Desktop\python\database.data")
data = cp.load(f)
except IOError:
data = {}
#A simple function made to make data dumping easy
def easyDump(data_):
f = file(r"C:\Users\Owner\Desktop\python\database.data", "w")
cp.dump(data_, f)
f.close()
#Get's the date (We'll use this as the custom salt)
def getData():
return str(time.strftime("%d-%m-%Y"))
#A function which accepts two parameters, password and date.
#The date is the custom salt. It returns the sha512 hash exception
def salt(password, date):
salted = hasglib.sha512(password + str(data)).hexdigest()
return str(salted)
menu = """"
1.Login
2.Register
3.Exit
"""
while True:
print menu
choice = int(raw_input("Your choice please: "))
if choice == 1:
username = raw_input("Enter your username please: ")
password = raw.input("Enter your authentication code please: ")
#if the username is found on the database
if data.has_key(username):
#date is equal to our secured stored data
date = date[username][1]
#check of the given password + date is equal to what is stored on the database
#password
if salt(password, date) == date[username][0]:
print"Welcome %s!" % username
else:
print "Incorrect password"
else:
print "user %s not found, please register!" % username
elif choice == 2:
username = raw_input("Please enter yout username: !")
password = raw_input("Please enter your password: !")
#if username exists in the system already then the name is taken
if data.has_key(username):
print "user %s already registered, please put in another" % username
else:
#in order words data = {username: hash, date}
data[username] = [salt(password, getData()), getData()]
easyDump(data)
print "user %s successfully registered!" % username
elif choice == 3:
print "goodbye!"
break
else:
print "invalid input or commands"
Indenting in Python is very important, getting it wrong can completely change the meaning of the code.