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.
#!/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.