Generate random passwords with bash

  •  
  •  

Normally, when I need some random passwords (or just a random string), I go to randomkeygen.com, copy the kind of password I need and off I go. But if you're a Linux user, like I am, you don't like leaving the terminal. So, I created a simple shorthand:

#!/bin/bash

echo -en "\n\e[0mStrong: \e[92m"
cat /dev/urandom | tr -dc "[:graph:]" | head -c 15

echo -en "\n\e[0mSafe chars:  \e[92m"
cat /dev/urandom | tr -dc 'a-zA-Z0-9@!.#%\-_' | head -c 20

echo -en "\n\e[0mFt Knox: \e[92m"
cat /dev/urandom | tr -dc "[:graph:]" | head -c 30

echo -en "\n\e[0mMemorable:   \e[92m"
shuf -n 4 /usr/share/dict/words | sed ':a;N;$!ba;s/\n/-/g;s/[A-Z]/\L/g;s/[^a-z-]//g'

echo -e "\e[0m"

You can just save this to randomkeygen.sh or into /usr/local/bin/randomkeygen to allow you to call randomkeygen when you need it.

Personally, I like wrapping it in a function and put it in my .bash_aliases file. This way, the function is only available to me as normal user:

function randomkeygen() {
  echo -en "\n\e[0mStrong:      \e[92m"
  cat /dev/urandom | tr -dc "[:graph:]" | head -c 15

  echo -en "\n\e[0mSafe chars:  \e[92m"
  cat /dev/urandom | tr -dc 'a-zA-Z0-9@!.#%\-_' | head -c 20

  echo -en "\n\e[0mFt Knox:     \e[92m"
  cat /dev/urandom | tr -dc "[:graph:]" | head -c 30

  echo -en "\n\e[0mMemorable:   \e[92m"
  shuf -n 4 /usr/share/dict/words | sed ':a;N;$!ba;s/\n/-/g;s/[A-Z]/\L/g;s/[^a-z-]//g'

  echo -e "\e[0m"
}

Put the above snippet into the ~/.bash_aliases file, then either restart the terminal or load the aliases manually:

. ~/.bashrc

Now, the randomkeygen function can be called wherever you want and it should generate something like this:

random passwords with bash example

Based on randomkeygen.com's code

Even though I got the main idea from a snippet I found on Github, the definitions for the passwords I found in randomkeygen's source code. Apart from replacing the character lists with tr's character classes, I've also removed the password forms that aren't used that often.

Finally I've added the memorable option, using the local dictionary to fetch random words from. This kind of password might not survive a very thorough dictionary attack, thus it looses in strength, yet it wins in usability. Great for use with e-mail accounts for example, if you're sure there's is some kind of brute-force protection in place.

Is this the best way to generate passwords?

No, probably not. This method reads the output of /dev/urandom, which generates random noise and only if the noise matches the pattern in tr it's added to the output. Since a lot of noise is thrown away, it's arguable the results might be biased. Some might say /dev/random is more random, but that's no longer the case.

Finally, there are many tools which allow you to generate passwords, like mkpasswd, makepassword, pwgen or secpwgen, but having a shortcut to the formats often used, beats them all in my opinion. Also, they probably also use /dev/urandom under the hood.

Changelog

  • 2024-03-01
    Removed Decent, CodeIgnighter, WPA and WEP outputs.
    Added Memorable output.