patternpythonMinor
Password generator in Python 3
Viewed 0 times
pythongeneratorpassword
Problem
I would like to see what you think of a password generator I coded in Python.
```
#A password generator in Python...Coded by Mcoury(python-scripter)
#import the necessary modules:
import base64
from Crypto.Hash import SHA512
import random
import pyperclip
print('+++Pypwd is a password generator in Python...Coded by Mcoury(python-scripter)+++')
print()
print()
print('Secure passwords must be strings of random characters, but humans are bad at generating random things...')
print()
print('''However, truly random strings are tricky to remember and impossible to reproduce.
Lose that precious txt file and you're out of luck!...''')
print()
print('''So I made this tool to solve the above problem,
all you have to remember is a short password (could be a name like smith),
a key a seed and 2 special characters(those are optional),
and 2 numbers(the borders of the slice the script will make)...''')
print()
plainpass=input('Please enter a password you can easily remember...')
prompt_key=input('Enter (y)es to use a multiplication key, or enter anything else if you wish to skip...').lower()
if prompt_key=='y': #A multiplication key will give potential attackers one more problem, but since it's not absolutely necessary, the user might want to skip selecting one
mult_key=int(input('Please enter a number...'))
else:
mult_key=1
newpass=plainpass*mult_key
def hashing():
'''Use SHA512 to hash our password'''
global hashedpass
h=SHA512.new()
bytepass=str.encode(newpass)
h.update(bytepass)
hashedpass=h.hexdigest()
base64_encode()
def base64_encode():
'''Encode the resulting hashed pass in base644 to increase length and complexity'''
global b64_4
bytehashedpass=str.encode(hashedpass)
b64_1=base64.b64encode(bytehashedpass)
b64_2=base64.b64encode(b64_1)
b64_3=base64.b64encode(b64_2)
b64_4=base64.b64encode(b64_3)
select_range()
def select_range():
'''Select a slice of the huge final base64 string '''
global dec
```
#A password generator in Python...Coded by Mcoury(python-scripter)
#import the necessary modules:
import base64
from Crypto.Hash import SHA512
import random
import pyperclip
print('+++Pypwd is a password generator in Python...Coded by Mcoury(python-scripter)+++')
print()
print()
print('Secure passwords must be strings of random characters, but humans are bad at generating random things...')
print()
print('''However, truly random strings are tricky to remember and impossible to reproduce.
Lose that precious txt file and you're out of luck!...''')
print()
print('''So I made this tool to solve the above problem,
all you have to remember is a short password (could be a name like smith),
a key a seed and 2 special characters(those are optional),
and 2 numbers(the borders of the slice the script will make)...''')
print()
plainpass=input('Please enter a password you can easily remember...')
prompt_key=input('Enter (y)es to use a multiplication key, or enter anything else if you wish to skip...').lower()
if prompt_key=='y': #A multiplication key will give potential attackers one more problem, but since it's not absolutely necessary, the user might want to skip selecting one
mult_key=int(input('Please enter a number...'))
else:
mult_key=1
newpass=plainpass*mult_key
def hashing():
'''Use SHA512 to hash our password'''
global hashedpass
h=SHA512.new()
bytepass=str.encode(newpass)
h.update(bytepass)
hashedpass=h.hexdigest()
base64_encode()
def base64_encode():
'''Encode the resulting hashed pass in base644 to increase length and complexity'''
global b64_4
bytehashedpass=str.encode(hashedpass)
b64_1=base64.b64encode(bytehashedpass)
b64_2=base64.b64encode(b64_1)
b64_3=base64.b64encode(b64_2)
b64_4=base64.b64encode(b64_3)
select_range()
def select_range():
'''Select a slice of the huge final base64 string '''
global dec
Solution
First, Because you are using pyperclip I assume you have read Al Sweigart's books, and if you haven't, you definitely should.
I think the symbol_insertion function is slightly more complicated than it needs to be. If I am understanding the code correctly, it seems like you are generating an array of 30 random integers. Then you are inserting the first symbol at the location specified by the 4th element of the array and the second symbol at the location specified by the 5th to last element of the array.
When testing the security of an algorithm it is common to assume that an attacker knows everything about it (including the source code) except for the key (which for this particular section of code I assume is the random seed and the two symbols). If that is the case then I think the following code is just as secure.
My reasoning behind this is that if I (an attacker) knew the random seed then it would be just as easy for me to generate a list of 30 random ints and use the 4th and 5th to last as it would for me to use just the first two. So you don't gain any additional security by generating the list of 30.
Overall, I think it's a good idea and implementation.
also:
can be written as simply
which is more pythonesque
I think the symbol_insertion function is slightly more complicated than it needs to be. If I am understanding the code correctly, it seems like you are generating an array of 30 random integers. Then you are inserting the first symbol at the location specified by the 4th element of the array and the second symbol at the location specified by the 5th to last element of the array.
When testing the security of an algorithm it is common to assume that an attacker knows everything about it (including the source code) except for the key (which for this particular section of code I assume is the random seed and the two symbols). If that is the case then I think the following code is just as secure.
def symbol_insertion():
'''give the user the choice to insert a couple special characters into the pass'''
check=input('To insert special chracters to the final string enter (y)es, enter anything else to skip...').lower()
if check == 'y':
mlist=[]
seed=int(input('Please enter the random seed...'))
random.seed(seed)
for i in range(2):
choice=random.randint(10,len(decoded_list)-1)
mlist.append(choice)
first_symbol=input('Please enter the first symbol...')
second_symbol=input('Please enter the 2nd symbol...')
decoded_list.insert(mlist[0],first_symbol)
decoded_list.insert(mlist[1],second_symbol)
finalresult=''.join(decoded_list)My reasoning behind this is that if I (an attacker) knew the random seed then it would be just as easy for me to generate a list of 30 random ints and use the 4th and 5th to last as it would for me to use just the first two. So you don't gain any additional security by generating the list of 30.
Overall, I think it's a good idea and implementation.
also:
decoded_list.insert(mlist[len(mlist)-5],second_symbol)can be written as simply
decoded_list.insert(mlist[-5],second_symbol)which is more pythonesque
Code Snippets
def symbol_insertion():
'''give the user the choice to insert a couple special characters into the pass'''
check=input('To insert special chracters to the final string enter (y)es, enter anything else to skip...').lower()
if check == 'y':
mlist=[]
seed=int(input('Please enter the random seed...'))
random.seed(seed)
for i in range(2):
choice=random.randint(10,len(decoded_list)-1)
mlist.append(choice)
first_symbol=input('Please enter the first symbol...')
second_symbol=input('Please enter the 2nd symbol...')
decoded_list.insert(mlist[0],first_symbol)
decoded_list.insert(mlist[1],second_symbol)
finalresult=''.join(decoded_list)decoded_list.insert(mlist[len(mlist)-5],second_symbol)decoded_list.insert(mlist[-5],second_symbol)Context
StackExchange Code Review Q#145842, answer score: 3
Revisions (0)
No revisions yet.