3
\$\begingroup\$

Below script is used to generate passphrases for gpg (or anything really).

Do you see any blatant security mistakes in it?

I wrote it by myself, because I couldn't find any passphrase generator that doesn't use external services and uses /dev/urandom.

Note: I run it with ./generator.bash 4 > x && vim x so stdout is not printed to the terminal, but I'm not sure if this is neccessary. I'm thinking that somewhere terminal history could be stored.

#!/bin/bash
# Usage: ./passphrase_gen.bash 4 > x && vim x
# We redirect to file and print via vim so no history is saved anywhere.
# Repeat after you get passphrase you like. Memorize it/write it down
# and remove x afterwards.
set -eo pipefail

words=/usr/share/dict/words

# https://serverfault.com/a/214620/216850
sudo rngd -r /dev/urandom

n=$1

# print $n randomly chosen words from $words file
for i in $(seq 1 $n); do
  # https://unix.stackexchange.com/a/268960
  random=$(od -vAn -N4 -tu4 < /dev/urandom)

  lines=$(cat $words | wc -l)

  line=$((random % lines))
  awk "NR==$line" $words
done

Gist link: https://gist.github.com/jan-swiecki/9974501047c79bad12a3c87cfe846cd6

\$\endgroup\$
1
  • \$\begingroup\$ You could usefully read the Diceware homepage which has a lot of advice about generating passphrases, as well as some useful (and large) wordlists. \$\endgroup\$
    – rossum
    Oct 20 '17 at 14:21
3
\$\begingroup\$

Note: I run it with ./generator.bash 4 > x && vim x so stdout is not printed to the terminal, but I'm not sure if this is neccessary. I'm thinking that somewhere terminal history could be stored.

I don't think this is necessary. If anything, you might forget to remove x, which could be a security risk.

Avoid seq

seq is not a standard tool, and a native alternative exists:

for ((i = 0; i < n; i++)); do ...; done

Extract constants out of loops

This statement is executed in each iteration of the loop:

lines=$(cat $words | wc -l)

But the content of the $words file is likely constant, so it's safe to compute this once, before entering the loop.

Unnecessary cat

The cat command is unnecessary with wc, it's better to redirect input:

lines=$(wc -l < "$words")

Double-quote variables in command line arguments

Although the content of $words doesn't contain spaces, as a good practice it's good to double-quote it when using as program arguments, for example instead of:

awk "NR==$line" $words

Write:

awk "NR==$line" "$words"

Arithmetic context

Instead of this:

line=$((random % lines))

You can write simpler:

((line = random % lines))
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.