add solution and minimal solution
This commit is contained in:
		
							parent
							
								
									20500431df
								
							
						
					
					
						commit
						f9db3c9c54
					
				
					 2 changed files with 130 additions and 0 deletions
				
			
		
							
								
								
									
										88
									
								
								auth.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								auth.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,88 @@
 | 
			
		|||
import getpass
 | 
			
		||||
import json
 | 
			
		||||
import pathlib
 | 
			
		||||
import random
 | 
			
		||||
import string
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
# name of the file where we store the pw database
 | 
			
		||||
PWDB_FLNAME = pathlib.Path('pwdb.json')
 | 
			
		||||
 | 
			
		||||
# list of valid characters for salt (only ASCII letters + digits + punctuation)
 | 
			
		||||
CHARS = string.ascii_letters + string.digits + string.punctuation
 | 
			
		||||
 | 
			
		||||
# length of salt
 | 
			
		||||
SALT_LENGTH = 5
 | 
			
		||||
 | 
			
		||||
def get_credentials():
 | 
			
		||||
    # get input from terminal
 | 
			
		||||
    username = input('Enter your username: ')
 | 
			
		||||
    # get password using the appropriate module, so that typed characters are not
 | 
			
		||||
    # echoed to the terminal
 | 
			
		||||
    password = getpass.getpass('Enter your password: ')
 | 
			
		||||
    return (username, password)
 | 
			
		||||
 | 
			
		||||
def authenticate(username, pass_text, pwdb):
 | 
			
		||||
    # get the salt from the database
 | 
			
		||||
    salt = pwdb[username][1]
 | 
			
		||||
    # calculate hash and compare with stored hash
 | 
			
		||||
    return pwhash(pass_text, salt) == pwdb[username][0]
 | 
			
		||||
 | 
			
		||||
def add_user(username, pwdb):
 | 
			
		||||
    # do not try to add a username twice
 | 
			
		||||
    if username in pwdb:
 | 
			
		||||
        raise Exception(f'Username already exists [{username}]!')
 | 
			
		||||
    else:
 | 
			
		||||
        password = getpass.getpass(f'Enter password for {username}: ')
 | 
			
		||||
        salt = get_salt()
 | 
			
		||||
        pwdb[username] = (pwhash(password,salt), salt)
 | 
			
		||||
    return pwdb
 | 
			
		||||
 | 
			
		||||
def read_pwdb(pwdb_path):
 | 
			
		||||
    if not pwdb_path.exists():
 | 
			
		||||
        pwdb = {}
 | 
			
		||||
    else:
 | 
			
		||||
        with open(pwdb_path, 'rt') as pwdb_file:
 | 
			
		||||
            pwdb = json.load(pwdb_file)
 | 
			
		||||
    return pwdb
 | 
			
		||||
 | 
			
		||||
def write_pwdb(pwdb, pwdb_path):
 | 
			
		||||
    with open(pwdb_path, 'wt') as pwdb_file:
 | 
			
		||||
        json.dump(pwdb, pwdb_file)
 | 
			
		||||
 | 
			
		||||
def pwhash(pass_text, salt):
 | 
			
		||||
    # simple additive hash -> very insecure!
 | 
			
		||||
    hash_ = 0
 | 
			
		||||
    full_pass_text = pass_text + salt
 | 
			
		||||
    for idx, char in enumerate(full_pass_text):
 | 
			
		||||
        # use idx as a multiplier, so that shuffling the characters returns a
 | 
			
		||||
        # different hash
 | 
			
		||||
        hash_ += (idx+1)*ord(char)
 | 
			
		||||
    return hash_
 | 
			
		||||
 | 
			
		||||
def get_salt():
 | 
			
		||||
    salt_chars = random.choices(CHARS, k=SALT_LENGTH)
 | 
			
		||||
    return ''.join(salt_chars)
 | 
			
		||||
 | 
			
		||||
def main(pwdb_path):
 | 
			
		||||
    # load the password database from file
 | 
			
		||||
    pwdb = read_pwdb(pwdb_path)
 | 
			
		||||
 | 
			
		||||
    # if we are passed an argument, we want to add a new user
 | 
			
		||||
    if len(sys.argv) > 1:
 | 
			
		||||
        pwdb = add_user(sys.argv[1], pwdb)
 | 
			
		||||
        write_pwdb(pwdb, pwdb_path)
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # ask for credentials
 | 
			
		||||
    username, password = get_credentials()
 | 
			
		||||
    if username not in pwdb or not authenticate(username, password, pwdb):
 | 
			
		||||
        print('Wrong username or password!')
 | 
			
		||||
    else:
 | 
			
		||||
        print('Successfully authenticated!')
 | 
			
		||||
 | 
			
		||||
    return
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    main(PWDB_FLNAME)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								minimal_auth.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								minimal_auth.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
import json
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
def get_credentials():
 | 
			
		||||
    username = input('Enter your username: ')
 | 
			
		||||
    password = input('Enter your password: ')
 | 
			
		||||
    return (username, password)
 | 
			
		||||
 | 
			
		||||
def authenticate(username, password, pwdb):
 | 
			
		||||
    return password == pwdb[username]
 | 
			
		||||
 | 
			
		||||
def add_user(username, pwdb):
 | 
			
		||||
    pwdb[username] = input(f'Enter password for {username}: ')
 | 
			
		||||
    return pwdb
 | 
			
		||||
 | 
			
		||||
def read_pwdb(pwdb_path):
 | 
			
		||||
    try:
 | 
			
		||||
        pwdb_file = open(pwdb_path, 'rt')
 | 
			
		||||
        pwdb = json.load(pwdb_file)
 | 
			
		||||
    except Exception:
 | 
			
		||||
        pwdb = {}
 | 
			
		||||
    return pwdb
 | 
			
		||||
 | 
			
		||||
def write_pwdb(pwdb, pwdb_path):
 | 
			
		||||
    pwdb_file = open(pwdb_path, 'wt')
 | 
			
		||||
    json.dump(pwdb, pwdb_file)
 | 
			
		||||
 | 
			
		||||
pwdb_path = 'pwdb.json'
 | 
			
		||||
pwdb = read_pwdb(pwdb_path)
 | 
			
		||||
 | 
			
		||||
if len(sys.argv) > 1:
 | 
			
		||||
    pwdb = add_user(sys.argv[1], pwdb)
 | 
			
		||||
    write_pwdb(pwdb, pwdb_path)
 | 
			
		||||
else:
 | 
			
		||||
    username, password = get_credentials()
 | 
			
		||||
    if username not in pwdb:
 | 
			
		||||
        print('Wrong username!')
 | 
			
		||||
    else:
 | 
			
		||||
        if authenticate(username, password, pwdb):
 | 
			
		||||
            print('Successfully authenticated!')
 | 
			
		||||
        else:
 | 
			
		||||
            print('Wrong password!')
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue