Compiling a custom passphrase wordlist

Published by Evan @ aleatoric

I compiled a custom wordlist to use when generating passphrases, and this site describes my approach. I had some dissatisfactions with the commonly recommended existing lists, so I put a little time into making one to my own specifications.

Here's my full custom wordlist if you want to explore the end result.

Before diving into the details, here's a passphrase generator that you can try out if you want to compare some sample passphrases generated by different wordlists.

Index
My words
Reinhold
EFF

Some background

Diceware is a method for generating passphrases using some dice and a list of words. You have a list of a certain number of words and roll some dice to pick random words from the list until you have as many as you want in your passphrase. I first learned about passphrases through Arnold G. Reinhold's Diceware Passphrase Home Page where you can read the detailed explanation if you want it.

Later, the Electronic Frontier Foundation (EFF) released New Wordlists for Random Passphrases. They listed several factors that motivated them to produce these alternative word lists, which are worth repeating in full here.

The Diceware list can provide strong security, but offers some challenges to usability. In particular, some of the words on the list can be hard to memorize, hard to spell, or easy to confuse with another word.

The EFF team also attempted to remove words that are difficult to spell or are homophones. Combined with the removal of words that are an exact prefix of another word, they seem to have removed many of the shorter words entirely. The resulting word list is not really to my liking. The words range from 3–9 characters in length, with an average of 7 characters. For a 5-word passphrase with spaces or some other separator between the words, this is an average of 39 characters to type.

For comparison, Reinhold's original list ranges from 1–6 characters, averaging out around 4.25 characters per word. That's closer to 24 characters, on average, for a 5-word passphrase, which is already quite a lot to type if you type in your passphrase several times a day.

So, after years of dissatisfaction with the long passphrases generated from the EFF list, I finally decided to try compiling my own personal word list. In the spirit of the section from the EFF quoted above, here are my own objections to the Reinhold and EFF word lists that I hoped to address in my custom wordlist.

In short, I think that the EFF lists are a good attempt at a general-purpose solution, but I just don't like how many long words they have. The Reinhold words have better lengths, but lean too heavily into nonsense strings for my taste.

For a little more context, here's a brief explanation about how I personally use passphrases.

Compiling my custom wordlist

First, I wanted a list of words to start from. Almost any modern unix-based system has a handy list of words somewhere, and that's what I used. I pulled all the 3–6 letter words (no punctuation or accented characters) from this list into a file for review. At this stage, I kept words with uppercase letters, because I wasn't sure yet what I was going to want to keep.

egrep "^[a-zA-Z]{3,6}$" /usr/share/dict/words > mywordlist.csv

This provided 20,132 words to start with. As a reminder, my target is 7,776 words.

Next, I rejected some kinds of offensive words ("words of oppression") that I didn't want to see in my passphrases. I used dariusk's wordfilter list to identify candidates that I then reviewed manually. I wasn't trying to remove all profanity and crass language at this stage, just taking a first filter against words that I expected to find most objectionable.

This removed 70 words, leaving 20,062 words.

I de-duplicated words that appeared in both uppercase and lowercase forms. For example, I discarded Mark because mark was already in the list, but kept Wendy since there was no lowercase equivalent.

This removed 703 words, leaving 19,359 remaining.

Now I took a first major review pass. Over the course of several days, I manually looked at all ~19,000 words and made a snap judgement about whether each word should be kept, rejected, or "maybe" kept. Going into this, I didn't really have any sense of what my criteria were, but a few common patterns emerged.

In total, this first review removed 10,106 words, leaving 9,253 remaining. I was pretty happy with this first pass.

After a break (several days or weeks, I forget exactly), I took another pass, looking at each of the remaining words on the "keep" list again and just being a little more picky, especially for 5 and 6 letter words. I cut several more words with common prefixes like unbend and unsung, some words of three or even four syllables, like vivify and iambic, words that I personally might expect to write with a hyphen or as separate words, like nonfat or earwax, and some more profanity or crass words.

Surprisingly, I cut 1,431 words in this pass, leaving 7,764 remaining. I had overshot my target by only a dozen words!

After a few easy tweaks, I got back to 7,776 words, and pretty much called this project done. The words range in length from 3–6 letters and average just below 5 letters per word. For a 5-word passphrase with separators, that averages out to 29 letters, which is not too bad in my opinion.

The last step was to downcase any remaining words. I ended up with several hundred personal names, place names, and other miscellaneous proper nouns (now in lower case) like july and sunday.

I'm sure that there are still some words in the list that I might prefer to reject for various reasons. I could keep tweaking it if I really wanted to, but after hitting my target so nicely, I didn't want to spend more time over-thinking it.