My password generator
How do you create a really good password that you don't need to remember but that you might occasionally need to write on paper or type into a keyboard? These days modern operating system provide really good sources of randomness, and one method that is often used is to read some randomness from the operating system PRNG located at /dev/random and run the data through the base64 encoding to get letters, numbers, + (plus) and / (slash). However, those passwords are not that conveinent and sometimes when I write them down people mistake my zeroes for capital o and things like that.
What I wanted was a password generator that could output a configurable length password using only easily distinguishable letters and numbers, so I wrote one. As usual I place this code in the public domain, feel free to use it any way you want.
Features:
- The entropy of the password is as good as the underlying operating system. If you use a recent Linux or OSX version, the data returned from /dev/random is quite good.
- The code is simple and it is easy to verify that the program actually uses the entropy that it reads.
- The resulting passwords are easy to type on keyboards and write on paper without confusing the reader with similar characters such as 1 (one) and l (lower case l).
- The length of the password is configurable.
#!/usr/bin/python import sys # alphanumeric chars minus l, I, O, 0, 1 alphabet = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789" # Some expeimentation told me that 2 ** 5.8 = 55.7 BITS_PER_CHAR = 5.8 # The default password length has the capacity of a bit more # than 64 bits of entropy. DEFAULT_LEN = 12 def main(args): count = DEFAULT_LEN if len(args) > 1: if args[1] == '-h': usage() return elif args[1] == '-c' and len(args) > 2: count = int(sys.argv[2]) else: usage() return print(create_password(count)) def string_to_bignum(s): num = 0 for c in s: num = ord(c) + (num << 8); return num def create_password(length): random = open("/dev/random", "r") needed_bytes = (int)(length * BITS_PER_CHAR) / 8 + 1 n = string_to_bignum(random.read(needed_bytes)) random.close() s = "" for i in xrange(length): s = s + alphabet[n % len(alphabet)] n = n / len(alphabet) return s def usage(): print """mkpasswd [-h] [-c COUNT] Create a random password using the operating system's entropy pool using a 57 character alphabet of letters and numbers. The characters in the alphabet excludes characters and letters easily confusable such as I and 1. Each password character holds about 5.8 bits of entropy, so the standard 12 character password can hold a theroretical maximum of 69 bits of entropy. The actual entropy present in any generated password is a function of the entropy gathering algortihm present in the kernel of your operating system. -h display this help text -c COUNT create a password with COUNT characters.""" if __name__ == '__main__': main(sys.argv)Filed under Cryptography, Programming | Comment (1)