Search

Generating Good Passwords, Part I

Dave starts a new method for generating secure passwords with the help of 1Password.

A while back I shared a script concept that would let you enter a proposed password
for an account and evaluate whether it was very good (well, maybe
"secure" would be a better word to describe the set of tests to ensure that
the proposed password included uppercase, lowercase, a digit and a punctuation
symbol to make it more unguessable).

Since then, however, I've really been trying personally to move
beyond mnemonic passwords of any sort to those that look more like gobbledygook.
You know what I mean—passwords like fRz3li,4qDP? that turn out to be
essentially random and, therefore, impossible to crack using any sort of dictionary
attack.

Aiding me with this is the terrific password manager 1Password. You can learn more
about it here, but the key feature I'm using is a
combination of having it securely store my passwords for hundreds of websites and
having a simple and straightforward password generator feature (Figure 1).

Figure 1. 1Password Password Generation System

If I'm working on the command line, however, why pop out to the program to get
a good password? Instead, a script can do the same thing, particularly if I again
tap into the useful $RANDOM shortcut for generating random numbers.

Generating Secure Passwords

The easiest way to fulfill this task is to have a general-purpose approach to
generating a random element from a specific set of possibilities. So, a random
uppercase letter might be generated like this:

To get even fancier, there's another notation ${#variable} that returns the
number of characters in a variable, so the following shows that there are 24
characters in that particular string:

$ echo ${#punct}
24

To be maximally
flexible, every reference can include that too, allowing me to add or delete
specific punctuation marks at will:

${punct:$(( $RANDOM % ${#punct} )):1}

It's starting to look a bit like my cat ran over the keyboard, but that's why I add
all the spaces here. Many script writers tend to eschew all those spaces and use
shorter variable names, but in my opinion, something like this is definitely harder to
read and understand:

${p:$(($RANDOM % ${#p})):1}

In fact, it reminds me of an old
programming language called APL where it was generally accepted that it was easier
to rewrite code than understand what someone else had done within a program. Yikes.

This solves the challenge of producing a random character in a specific charset,
I'll defer the next piece of the script until my next column, at which point
I'll show how to build a sequence of these random characters to create a
string of the desired length and complexity.

Dave Taylor has been hacking shell scripts on UNIX and Linux systems for a
really long time. He's the author of Learning Unix for Mac OS
X and Wicked Cool Shell Scripts. You can find him on Twitter
as @DaveTaylor, and you can reach him through his tech Q&A site: Ask Dave Taylor.