Password Generation

There are lots of ways of generating passwords. We can use dashboard widgets, desktop applications or even websites. I’ve recommended GRC’s password generator in the past (https://www.grc.com/passwords.htm) as it’s quick and easy.

The password below is random. Try refreshing the page!

]Y{A]h6j1v\z0x7U2q3Z]W.r,a(B.a|G5m.r#c/v


I tend to use Apple’s password generator, which can be found in the change password sheet available through the Accounts preference pane.

When I don’t have access to the GUI though I revert to a few simple scripts, which I’ve included below.

The first uses the OpenSSH library bundled with Ruby. It asks for a string to push through an AES encryption algorithm and will print both the encrypted string and a decrypted string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env ruby -wdK
 
require "digest/sha1"
require "openssl"
require "base64"
 
if ARGV.length == 0
  puts "Usage: #{File.basename($PROGRAM_NAME)} input_string"
  exit
end
 
def encrypt(plaintext, salt = "%jha&%£Hkjhae5hH£5k£$HKJF7@EEE")
  aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
  aes.encrypt
  aes.key = Digest::SHA1.hexdigest(salt)
 
  out = aes.update(plaintext)
  out << aes.final
  Base64.encode64(out)
end
 
def decrypt(ciphertext, salt = "%jha&%£Hkjhae5hH£5k£$HKJF7@EEE")
  aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
  aes.decrypt
  aes.key = Digest::SHA1.hexdigest(salt)
 
  out = aes.update(Base64.decode64(ciphertext))
  out << aes.final
  out
end
 
enc = encrypt(ARGV[0].downcase)
 
puts "Input String: #{ARGV[0].downcase}"
puts "Encrypted: #{enc}", "Decrypted: #{decrypt(enc)}"

In theory the aes.key generation step that uses SHA1 and the salt variable is unnecessary. We could use the same key every time or let OpenSSL handle key generation for us.

Accessing the script from the command line yields the following:

$ ruby keygen.rb 'OurStringToEncrypt'
Input String: ourstringtoencrypt
Encrypted: jljJEY+vLtNzIPNMg0iIVviONKURdX6/7uIxE4P2dpw=
Decrypted: ourstringtoencrypt

An alternate script is a really simple SHA1 hash that generates a fixed-length hash of hexadecimal characters. Not the most secure password but it’s quick and easy.

An example of what this yeilds is below.

ruby simple_hash.rb 'A Simple String'
02e48eed167d25f5f13355cbafb758eccebba439

Finally there’s a PHP script I used to generate the password printed at the top of this post. It’s really quite simple and limits users to a 500 character maximum length. The source is below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function generatePassword($length) {
	if ($length > 500) {
		header("Location: http://code.theonlyjames.com/password.php?length=500");
		exit;
	}
 
	$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	$special = '0123456789@#$%-_.,:;!+|[]{}()/';
 
	$password = '';
	$alt = time() % 2;
	for ($i = 0; $i < $length; $i++) {
		if ($alt == 1) {
			$password .= $chars[(rand() % strlen($chars))];
			$alt = 0;
		} else {
			$password .= $special[(rand() % strlen($special))];
			$alt = 1;
		}
	}
	return $password;
}
 
header("Content-type: text/plain");
 
$g_int = isset($_GET['length']) ? $_GET['length'] : 40;
 
if (is_numeric($g_int)) {
	echo generatePassword( floor($g_int) );
} else {
	echo generatePassword(40);
}

If you need to generate passwords that vary with time you can use a hash of the current time with some sort of salt. I needed a system that would generate a new password every minute should it be required.

#!/usr/bin/ruby
 
require "digest"
 
def generate_hash(input)
  # Generate two hashes both based on an input with the a time stamp
  # To generate a password more frequently you could add a second to
  # the timestamp in digest1 or digest2. For example digest2 could
  # use Time.now.strftime("%Y%m%s")
  digest1 = Digest::SHA1.hexdigest(input + ' == ' + Time.now.strftime("%D%H"))
  digest2 = Digest::SHA1.hexdigest(input + ' == ' + Time.now.strftime("%Y%m"))
 
  # This is where we do all of our digesting ; )
  stomach = ""
 
  # Here we join digest1 and digest2 character by character to form a
  # slightly more complicated output that would a little harder to
  # replicate (but only a little!)
  digest1.length.times do |n|
    stomach << digest1[n]
    stomach << digest2[n]
  end
 
  # Now we let the Digest module do the hard work
  Digest::SHA1.hexdigest(stomach)
end
 
# This is just a repetitive loop for testing the result of generate_hash
# every couple of seconds.
5.times do |n|
  if n > 0
    sleep 2
  end
  int = (n + 1).to_s
  hash = generate_hash('james_123')
 
  # Print the current time and our hash
  puts Time.now.to_s + ":\n" + hash
end

One Response to “Password Generation” — Comments Feed

  1. OpenSSH Keys — The Only James

    April 11, 2008 at 10:40 am

    [...] secure! I’ve made a couple of scripts that will generate passwords, which you can find in my password generation [...]

Leave a Reply