Friday, June 8, 2012

Offline Password Creator

UPDATE: Please read my update on password security, as this post is no longer good advice but will be left up for archival purposes.


Inspired by the xkcd comic Password Strength, I decided to write a python script that will create a password encryption scheme.

from xkcd.com
The problem I have with idea of choosing four random words is the fact that you still want a different set for each website (in case of attacks).

My solution was to create a list with a word associated with each letter from A to Z. The python script takes input from the given word list (aka dictionary) and randomly selects words for each letter and then spits out into a text file. It's quite easy to change the dictionary file just edit the line 
filename = "crossword_wordlist.txt"
to the file name you want. However the file must contains words that start with each letter (they do not have to be in order though).

The seed for the random number generator is based on the current time, and should be quite different for everyone to ensure it's difficult to duplicate.

Where to Download
You can grab a copy of the python script (with a random dictionary) from the gist/github page
For the lazy: Direct Download
(Code is pasted at the bottom as well)

How to Use
Here's my quick method for creating unique passwords for each site.
First save and/or print the file once you generate a list.
example list:
antileak
butles
collaged
duvet
egyptian
fenurons
gruyeres
hahas
ionogens
jovialty
kbars
logania
malteds
naturism
overdubs
prefire
quashers
releve
shickers
tavernas
undocile
varoomed
wonk
xanthans
yuppies
zlote
Then pick a website you want to create an account on. Let's say Blogger.com:
Take the first 4 letters of the site name (B, L, O, G in this case) and find the words for those letters and voila! You have your password! (butlesloganiaoverdubsgruyeres in this case).
Now some sites require upper-case and/or numbers so I'd use something easy like the first word in all caps, or every other letter in caps and then pick a number to use at a pre-determined spot. Then keep that little part consistent across sites (unless you want to come up with a system for caps and numbers. I may write a script to do it soon myself).

So this gives you a unique formula to create simple, secure passwords for any website without memorizing anything too crazy.

Comments and criticism are appreciated!


import os
import time
import random
 
## Variables ##
filename = "crossword_wordlist.txt" #file to load
path = os.path.abspath(os.curdir) #path to said file
 
output_filepath = path+"/offline_password_encryption_key.txt"
 
## Makes a list of lists. Each inner list (henceforth 'wordlist') will contain all the
## words starting with the appropriate letter (alphabet[0]=a, alphabet[1]=b, etc)
alphabet = [ list() for x in range(ord('a'),ord('z')+1)]
 
WORDFILE = open(path+"/"+filename, "r+") #gives us the file of words to use
code = "" #creates an empty string
random.seed(time.time()) #creates a random num generator with a unique seed based on the time you run the program
''' Intro '''
print "============================="
print "Offline Password Creator v1.0"
print "by James Firth"
print "============================="
 
 
 
''' Code that actually excutes stuff '''
 
 
#add all the words in the file to the appropriate wordlist
print "Adding words to dictionary..."
for line in WORDFILE:
 wordlist = alphabet[ord(line[0])-97] #find the index and grabs that wordlist
 wordlist.append(line) #append the new word to the wordlist
 
WORDFILE.close() #closing the file like a good little boy
 
 
print "Selecting our list of encryption words..."
 
#for all the letter in the alphabet
#picks a random number in the appropriate range
#grabs the right word. And appends to the encryption list
for wordlist in alphabet:
 if len(wordlist) > 0: 
  ranIndex = random.randint(0,len(wordlist)-1)
  chosen_word = wordlist[ranIndex] 
  code += (chosen_word)
  
OUTPUTFILE = open(output_filepath,"w+") #open the outpute file
print "Saving to file..."
OUTPUTFILE.write(code)
OUTPUTFILE.close()
print "~~ DONE!~~ \nYour Encryption Keys can be found at: "+output_filepath