Generating Passwords

I've recently been using hash generated passwords with customers as a more secure alternative to weak "default" passwords.

I got the idea from the Lesspass [1] browser extension. With Lesspass you create passwords from a hash using known elements like your preferred username, the website, and a master passphrase. There is no password storage, you calculate the passwords from those elements each time.

While this is absolutely not as good as long cryptographically strong random passwords, I believe hashed passwords are an acceptable and reproducible compromise during a project. Weak default passwords are too often not changed before entering production, creating a potential exposure for customers.

Strong passwords typically have to be recorded in a password manager, and should not exist in plain text in any file. As a consultant I don't want access to customer's password vault application. We all know not to store sensitive passwords in plain text format on any system.

I always recommend that all passwords be changed once I am done with a project. Often this doesn't happen, so it's in everyone's best interest to use a stronger password during the build.

This method is done completely at the AIX command line, without needing any additional software.

Why a hash?

A hash function [2] like MD5 and SHA1 can take inputs of any length and compute a fixed length hash value. This hash value is always the same for the same input. If we use the hash value as a password, then we know we can recreate the password.

Using a good hash function the original inputs cannot be derived from the hash. Unfortunately because hashes are fast to compute, they are subject to brute force attempts to guess all potential inputs to the hash to try and reproduce the hashed value.

Since I intend to use the hash value as a password, I need to add a "salt" to strengthen the hash and prevent brute force attempts. For that I use a long random string added to the input to the hash. This salt is in effect a master password.

I can use AIX commands to generate a strong salt value, and save it in a file on the customer system. We can use that to generate passwords, and I don't keep a record of that salt.

Generating a salt

Because we'll use a hash of known elements to create a password, and those elements are easy to guess and short, we need a long and strong salt value. For example:

% openssl rand -hex 128
63766fbe7f197c5c1191e415869e71314c18e7ab96eea1635f3a630032eb2c96d812d2774347ca0d9f44ed613b6f56d0d5cf059c262657ba29572768fa4d280655a460ca27b6cbdb48d8a7f1ab80dccaa99533d9197917abea1fe8934980f4c19713d26885ffed3076e264816c7dd2e5e0327376efed8cd9bc97e82507011875

This generates a random hexadecimal string 128 characters long. Saving this to a file will let me use the salt later for password generation:

% mkdir secure
% chmod 700 secure
% openssl rand -hex 128 > secure/salt.txt
% chmod 400 secure/salt.txt

Larger values could be used, but I think 128 characters is sufficient when generating a temporary password that should be changed later.

Generating a password

To generate a password, I must consistently use the same inputs. I use the lowercase username, lowercase short hostname, a project name, and the salt. These are used with echo to pipe to openssl to create a hash of the inputs:

% echo "user@hostname aixproject 2021 $(cat secure/salt.txt)" | openssl dgst -sha1
(stdin)= dd93db5a29ed10c74fb54999d1ddc30cd3f66e23

The hashed value "dd93db5a29ed10c74fb54999d1ddc30cd3f66e23" is a pretty strong password. If a shorter password is needed, use -md5 or truncate the password to fit the application.

As long as the same inputs are used, the resulting hash value will always be the same.

The salt is not included in the shell history.

Remember in AIX user accounts are limited to the first 8 characters of the password unless you update your password hash algorithm! [3]

Scripted password generation

Consistency is key, and always using the command line directly isn't always optimum. Throwing together a short script makes this even easier.

hashpass.sh (Source)

#!/bin/sh

echo Enter username:
read MYUSER
echo Enter short hostname:
read MYHOST
echo Password:
echo "${MYUSER}@${MYHOST} myproject 2021 $(cat secure/salt.txt)" | openssl dgst -sha1 | cut -f2 -d ' '

That's a bit cleaner:

% ./hashpass.sh
Enter username:
user
Enter short hostname:
hostname
Password:
dd93db5a29ed10c74fb54999d1ddc30cd3f66e23

Summary

Generated passwords are more secure than weak, short, default passwords. Using a strong salt on a trusted system, generating passwords allows for creation of modestly secure, reproducible passwords within an environment.

Remember to replace these passwords with a strong random password before going to production!

Update

I had some additional discussion over passwords with additional characters and other algorithms, and a few other links came up and a new piece of code.

This blog has a good review of many hash methods. I agree with the author that password hashing should not be used for important passwords, but my example is using them for building systems instead of insecure defaults.

One of the discussions brings up a code sample used by "hashapass", which can be used on many UNIX systems with openssl.

Adapting this to AIX and the examples I have provided results in the following updated code:

% echo "user@hostname aixproject 2021" | openssl dgst -sha256 -binary -hmac "$(cat secure/salt.txt)" | openssl enc -base64
a9Gfd1BoFJcsEwXzv9KW/NGenNHH05lF5oYRjWGIIm8=

The output can be cut to 16 characters or less if needed. Recent versions of OpenSSL also support SHA-512 (-sha512), and the output would need to be truncated.

I think this is a great improvement.