Password Generator

I myself have become more and more concerned about password security. So, I decided to write a little app that would generate random passwords for me. As for the volunteer part, I’m posting it here hoping that other interested parties will contribute their own password generators, so we can have a community collection to choose from.

Possible applications of all of this?

  1. Online game development. Say you’re creating an online game and players have to create an account with you to log on. Want to auto-generate random passwords for them? Well here you go.
  2. If you’re using wireless routers at home, you ought to have encryption keys on that connection, and you know it.
  3. If you’re like me, you’re going through and changing all your important online passwords to strong random passwords because paranoia is fun. :slight_smile: Put it on a flash drive and generate passwords anytime you need one.

I am aware that there are apps already existing that will do this for you, but it’s a fun, and really easy thing to do.

Unfortunately I don’t currently have web space to post it, but it’s so short that I’ll just post the code instead.

A) The first block of code is the interface that you should implement if you want to create your own password generator.
B) The second block is an example implementation that I’m currently using to generate random passwords - good for tutorial work too.
C) The third block is an actual command-line utility you can compile use to generate the passwords, using the Base32Generator class I provided, and output to a file. It’s easy to use and documented.

All 100% Java, and no UI stuff as of yet, so no quirky AWT/Swing problems to worry about.

Open for comments/contributions.


package password.generators;

/** The interface that all password generators should implement.
 * 
 * @author Jeff Lunt
 */
public interface PasswordGenerator {

	/** Gets the next password from this PasswordGenerator.
	 * NOTE to implementing classes: If the 'length' parameter passed to the 'setPasswordLength()'
	 * method is <= 0, then this method should return a zero-length String.
	 * 
	 * @return the next generated password from this PasswordGenerator.
	 */
	public String getNextPassword();
	
	
	/** Gets a String that tells the relative strength of the passwords made by this Generator.
	 * And example of a possible return value is, "Weak", "Strong", or something more useful like,
	 * "This is slightly stronger than a 40-bit password."
	 * 
	 * @return a String telling the user how strong passwords made by this Generator are likely to be.
	 */ 
	public String getStrength();
	
	
	/** Gets the length of passwords (in number of digits) created by this Generator.
	 * 
	 * @return the length of passwords made by this Generator.
	 */
	public int getPasswordLength();
	
	
	/** Sets the length of passwords (in number of digits) created by this Generator.
	 * 
	 * @param length the desired length of passwords made by this Generator.
	 */
	public void setPasswordLength(int length);
	
}


package password.generators;

/** Generates base 32 passwords. That is, passwords which use as their digits, lowercase letters a-z, and
 * numbers 0-5 (32 possibilities per digit in the password).
 * 
 * @author Jeff Lunt
 */
public class Base32Generator implements PasswordGenerator {

	public static final int DEFAULT_LENGTH = 8;
	public static final char[] base32Digits = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
		  									'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
		  									'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
		  									'y', 'z', '0', '1', '2', '3', '4', '5'};
	
	private int numDigits;
	
	
	/** Creates a base-32 password generator which outputs passwords containing the specified number of base-32 digits.
	 * 
	 * @param numDigits the length of passwords returned by this Generator.
	 */
	public Base32Generator() {
		this.numDigits = DEFAULT_LENGTH;
	}
	
	
	public String getNextPassword() {
		StringBuffer pwBuffer = new StringBuffer();
		
		for (int i = 0; i < numDigits; i++) {
			int currDigit = (int) (Math.random() * base32Digits.length);
			pwBuffer.append(base32Digits[currDigit]);
		}
		
		return pwBuffer.toString();
	}
	
	
	public String getStrength() {
		int bitStrength = 5*getPasswordLength();
		
		return ("Equivalent to " + bitStrength + "-bit password.");
	}
	
	
	public int getPasswordLength() {
		return this.numDigits;
	}
	
	
	public void setPasswordLength(int length) {
		this.numDigits = length;
	}

}



import java.io.*;

import password.generators.Base32Generator;

/** This class executes the base 32 generator.
 * 
 * @author Jeff Lunt
 * @version 2.00
 */
public class PWG {
	
	public static void main(String[] args) {
		int numDigits = 0;
		int numPasswords = 0;
		File outputFile = null;
		BufferedWriter out = null;
		
		try {
			numDigits = Integer.parseInt(args[0]);
			numPasswords = Integer.parseInt(args[1]);
			
			if (args.length == 3) {
				outputFile = new File(args[2]);
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile)));
			}
			
			if (args.length > 3)
				throw new Exception("Invalid number of arguments.");
		} catch (Exception ex) {
			printUsage();
			System.exit(1);
		}
		
		// Output password
		System.out.println();
		
		Base32Generator b32Gen = new Base32Generator();
		b32Gen.setPasswordLength(numDigits);
		for (int j = 0; j < numPasswords; j++) {
			if (out != null) {
				try {
					String password = b32Gen.getNextPassword();
					out.write(password, 0, password.length());
					out.newLine();
				} catch (IOException ioEx) {
					System.err.println("Cannot output passwords to file - an I/O error has occured.");
					System.exit(2);
				}
			} else {
				System.out.println(b32Gen.getNextPassword());
			}
		}
		
		try {
			if (out != null) {
				out.flush();
				out.close();
			}
		} catch (IOException ioEx) {
			// Useless, unrecoverable error
		}
		
		System.out.println(b32Gen.getStrength());
		System.out.println();
	}
	
	
	public static void printUsage() {
		System.out.println();
		System.out.println("PWG <digits> <passwords> [output]");
		System.out.println();
		System.out.println("digits    The number of digits in each generated password.");
		System.out.println("passwords The number of passwords to generate.");
		System.out.println("output    The filename where the passwords will be dumped.");
		System.out.println();
	}
	
}

Heh, do we need a framework for what could be done with 3-lines of code ?


                int minPasswordLength = 10;
                String randomPassword="";
                while (randomPassword.length()<minPasswordLength){
                    randomPassword += Integer.toString((int) (Math.random() * Integer.MAX_VALUE), Character.MAX_RADIX);
                }
                randomPassword=randomPassword.substring(0,minPasswordLength);

No, clearly you don’t. That was obvious to me when I wrote it - it’s just something for people to play around with, nothing more.

However, frameworks exist so that they can be easily extended. What if you want to generate passwords that are easy to remember (as opposed to totally random), but don’t want to human bias in choosing them? What if you want to generate passwords that (because of the requirement of the system) have to be purely numeric, or they have to start with a letter, or maybe you need one generated from a cryptographically secure pseudo random number generator, etc., etc., etc. Different generators for different pattern requirements. That’s clearly the purpose of this.

Also if you are creating a password that needs to be shown to the receiver you generally dont want to use:

i I
j
l
1

lower case i and j and lower case L or upper case I or 1, because in some fonts they look too similar. Sometimes an upper case I and 1 are identical. This is why all the CDkeys you get on games use all capitals and numbers, no lowercase and they probably omit characters. They are also more carefull now about picking fonts.