Image of the glider from the Game of Life by John Conway
Skip to content

Automated Diceware Passwords

For those unfamiliar, Diceware.com is a way of picking truly random passphrases from a predefined dictionary list of words. The idea is that each word has a 5 digit number attached to it. Each digit in the number holds the values 1-6, in numerical order. So, the first password starts with 11111, then 11112, 11113, 11114, 11115, 11116, then moving to 11121, etc. There are 7,776 words in the list. You can find the list at http://world.std.com/~reinhold/diceware.wordlist.asc. Now, take 5 fair 6-sided dice, and throw them one at a time. Take note of the numbers that fall out. After all 5 are thrown, find the corrensponding word in the dictionary list. This becomes the first word of your passphrase. Continue in like manner 5, 6 or more times, until you have a long passphrase.

For example, suppose you rolled in succession, 12345 64213 43526 13243 44615. In this case, your passphrase would be "apathywildninebalepabst". If you're curious about the entropy size this password belongs to, you can calculate it this way:

H = L * log2(N)
H = entropy in binary bits
L = length of your password
log2(N) = log(n)/log(2)
N = full size of the set(s) in your passwords

So N in our case is 7776, seeing as though each word belongs to that set, and is equally likely to appear and L = 5 (the "length" of your passphrase, in this case counting the number of words you picked). This, your entropy is 64 bits. In fact, each word in the diceware list comes with about 12.9248 bits itself. 64 bits is okay, but 77 bits, or 6 words, is much better. For comparison sake, compare http://stats.distributed.net/projects.php?project_id=8, which is a distributed computing project working at brute forcing a 72-bit entropy private RSA key. Look at their current pace of ~390 billion keys per second. To have a 100% guarantee they have found the key, it will take about 250 years to exhaust the entire key space at that pace, which is mostly GPU clients. The $500 video cards on the market today can do about 5 billion RSA keys per second. Thus, 78 of those cards, at a cost of $39,000 would maintain the pace that distributed computing project is seeing.

So, seeing as though diceware is a great way to create awesome passwords, I thought "why not develop this in a shell script?" So, I did so. See the script below. It does require that the diceware word liste in the same directory as the shell script. It can take a numeric argument at the number of words that should be included into the passphrase, or it can be run without an argument, in which case it will default to 6 words (77 bits of entropy).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/zsh

# ZSH script to create true random diceware passphrases. Requires
# diceware.wordlist.asc to be present in the same directory as the script.
# Can be found at http://world.std.com/~reinhold/diceware.wordlist.asc
#
# Author: Aaron Toponce <aaron.toponce@gmail.com>
# Date: Sept 20, 2012
# License: Public Domain

BASEDIR="$(echo "${0%/*}")"
WORDLIST="$BASEDIR/diceware.wordlist.asc"

if [[ ! -f "$WORDLIST" ]]; then
    echo "The diceware.wordlist.asc file must be present in the same"
    echo "directory as the diceware.zsh script."
    echo # Blank line
    echo "http://world.std.com/~reinhold/diceware.wordlist.asc"
    exit 1
fi

# Function to generate each Diceware word from the list
function five-dice-roll {
    echo -n $(< /dev/random tr -dc 1-6 | head -c 5)
}

# Function to find the Diceware word based on our dice roll
function diceware-word {
    awk "/$(five-dice-roll)/ {print \$2}" "$WORDLIST"
}

if [[ "$1" = <-> ]]; then NUM="$1"; else NUM=6; fi

for i in {1.."$NUM"}; do
    DICEPASS="${DICEPASS}$(diceware-word)"
done

echo "$DICEPASS"

Here is an example of using the shell script to generate 7 passphrases. And yes, it is using true random numbers for the fair 6-sided die, which is completely unweighted (better than you can say for any physical fabricated die):

$ for i in {1..7}; do echo -n "$i: "; ./diceware.zsh; done
1: remanerosphonytuftcopewaggle
2: paeandickalecktggoodell
3: nodalknickameshfpatpiotr
4: epiclostgamarabsiftmarx
5: pourpaxvalueaorta9ve
6: apexantileas'ssteelefrye
7: smeltgorseimpocwhiffgray

Post a Comment

Your email is never published nor shared.

Switch to our mobile site