4

There are many password generators around, but since uniformly randomly generated passphrases are preferable in many instances, I'm specifically looking for a generator of random and secure passphrases. I would like to be able to use it off-line (for security reasons) under Linux.

It should:

  • generate the passphrases off-line
  • work on Linux (although cross-platform solutions are ultimately preferred)
  • be open-source

And optionally, it would be nice if it could:

  • be able to use dictionaries from different languages (i.e. not necessarily limit itself to English)
  • (in a perfect world) be able to mix dictionaries, and generate passphrases that are a mixture of languages (e.g. English and German)
  • display the entropy of the generated password
  • What OS are you wanting this for? – Ken Herbert Nov 5 '14 at 3:55
  • Are you gravitating towards pass phrases so that you can remember them for multiple sites? If so, doesn't it make more sense to brainstorm them yourself? If you plan to use a password manager for the pass phrases, it would make more sense to just use long randomly generated passwords. A 50-character pass phrase is less secure than a randomly generated 50-character password. That XKCD is comparing long pass phrases to short passwords. – ZeroFlux Jan 23 '15 at 19:31
  • @ZeroFlux "doesn't it make more sense to brainstorm them yourself?" Not quite: "the selection of words must be (uniformly) random. If you ask humans to pick words at random, you get a heavy bias for concrete nouns. Such biases can and will be exploited." My interest is to come up with master passwords, something ultimately usable but secure, that I would use for instance to secure the password manager itself... – landroni Jan 23 '15 at 19:45
  • Ah, sorry, I see the confusion. I didn't mean trying to generate a secure pass phrase mentally, but rather using whatever tools strike your fancy to select the words themselves. There are so many resources out there to do so, it seemed like a logical place to start. But you've confirmed your interest in pass phrases, so I'll try to chip in an answer. creativitygames.net/random-word-generator linuxconfig.org/random-word-generator stackoverflow.org/wiki/… stackoverflow.com/questions/18834636/… – ZeroFlux Jan 23 '15 at 19:55
  • @ZeroFlux Ultimately any tool that can be used to output a selection of random words from a local dictionary would work just as nicely for this purpose, as long as the RNG is of good quality. But unfortunately this precludes the use of websites like the one you propose, or online passphrase generators like this one. – landroni Jan 23 '15 at 20:12
2

Ipsum

I also wanted a random word generator for creating passwords and couldn't find anything, so I created Ipsum. It is a bash script (intended to be used from the terminal). Ipsum satisfies these criteria:

  • Off-line: uses dictionary, so no internet needed
  • Linux: it is a bash script, so it is Linux compatible
    • Note: may need to modify the location of the dictionary
  • Open Source: the code is public domain
  • Languages: can generate random words from non-English languages
  • Random: this uses /dev/urandom which apparently is a 'cryptographic PRNG'
  • Entropy: has option to display the entropy of the generated words

Usage

Here are some examples to illustrate how Ipsum works. It is also important to know that when translating, Ipsum displays the English word beneath the translated word and not all random words will translate. Once Ipsum generates a list of words (in whatever language you want), simply choose a subset to use as a password.

Default

$ ipsum
unbalanced

Specify Number

$ ipsum 12
tramp
cutoff
scoured
sundowns
indigence
pellagra
offs
heaping
peevishly
judiciary
unmerciful
haul

Alternative Language [German]

$ ipsum --lang de 5
enormousness
   ^ enormousness
Tonsuren
   ^ tonsures
Harfenist
   ^ harpist
Oligarchie
   ^ oligarchy
nachlassen
   ^ letup

Alternative Language [Japanese]

$ ipsum -l ja 5
再要求
   ^ reclaims
喫水線
   ^ waterline
同意しません
   ^ disagree
皮質
   ^ cortex
リクルーター
   ^ recruiter

Bits of Entropy

$ ipsum --entropy 4
4 word(s) from 1 language(s) produces 65.36 bits of entropy.

happening
commander
parred
woodland

Source Code

This is kinda long, but I thought I'd provide it for your browsing pleasure. Here is the gist for it.

#!/bin/bash
function ipsum
{
    # Random Word Generator 
    # Inspired by:
    #      - https://linuxconfig.org/random-word-generator
    #      - http://stackoverflow.com/a/14203146/4769802
    #      - http://www.unix.com/shell-programming-and-scripting/156551-check-whether-string-begin-uppercase-lowercase-digit.html 
    #
    # Depends on:
    #      - translate-shell: https://github.com/soimort/translate-shell
    #        - This ^ thing is awesome. Seriously, try it out!


#-----------------------------------------------------------------Constants 
    X=0
    COUNT=1
    MAX_INT=16777216
    LANGUAGE=false
    LANGUAGES="en"
    NUM_LANGUAGES=1
    ENTROPY=false
    ALL_NON_RANDOM_WORDS=/usr/share/dict/words # dictionary file
    non_random_words=`cat $ALL_NON_RANDOM_WORDS | wc -l` # total # of words 
    proper_nouns=`cat $ALL_NON_RANDOM_WORDS | grep [A-Z].* | wc -l` # apprx # of proper nouns
    total_options=$((non_random_words - proper_nouns)) # apprx # of options

#-----------------------------------------------------------------Handle Flags w. Params
    while [[ $# -gt 1 ]]
    do
        key="$1"
        case $key in
            -e|--entropy)
                    # print the entropy
                    ENTROPY=true
                    ;;
            -l|--lang)
                    # Get the specifed languages!
                    LANGUAGE=true
                    LANGUAGES=(${2//+/ })
                    NUM_LANGUAGES=${#LANGUAGES[@]}
                    shift # past argument
                    ;;
            --lang-all)
                    # Use top 10 languages at once!
                    LANGUAGE=true
                    LANGUAGES=(zh pt es bn en ru hi ja ar pa)
                    NUM_LANGUAGES=${#LANGUAGES[@]}
                    ;;
            *)
                    echo "Unrecognized argument: try 'ipsum --help'"
                    exit
                    ;;
    esac
    shift # past argument or value
    done

#-----------------------------------------------------------------Handle Main Param
    if [[ -n $1 ]]; then
        case $1 in
            -a|--about)
                    # Give a description of self
                    echo "Ipsum is a minimalist random word generator"
                    echo "with several notable features:"
                    echo "       - Off-line: uses local dictionary so"
                    echo "                   no internet is needed"
                    echo "       - Languages: can generate non-English words"
                    echo "          - Note: this requires the internet"
                    echo "       - Random: uses '/dev/urandom' which is a CSPRNG"
                    echo "       - Entropy: calculates entropy of requested word combo"
                    echo ""
                    exit
                    ;;
            -h|--help)
                    # Show some examples
                    echo ""
                    echo "Example Usage: ipsum"
                    echo "               ipsum 12"
                    echo "               ipsum -lang fr 12"
                    echo "               ipsum -l fr 12"
                    echo "               ipsum -l fr+ru 12"
                    echo "               ipsum --entropy 12"
                    echo "               ipsum -e 12"
                    echo "               ipsum -l fr+ru -e 12"
                    echo ""
                    echo "Language Options:"
                    echo "               - Found here :: https://github.com/soimort/translate-shell"
                    echo ""
                    exit
                    ;;
            -i|--info)
                    # Show information about numbers and such
                    echo ""
                    echo "Dictionary Location: $ALL_NON_RANDOM_WORDS"
                    echo "Dictionary Size:     $non_random_words"
                    echo "Proper Nouns:        $proper_nouns"
                    echo "Usable Words:        $total_options"
                    echo "Default Language:    $LANGUAGES"
                    echo "Possible Languages:  124"
                    echo "      _________________________________ "
                    echo "     |  Top Ten Most Common Languages  |"
                    echo "     |----------------|----------------|"
                    echo "     | Chinese - zh   | Portuguese - pt|"
                    echo "     | Spanish - es   | Bengali  - bn  |"
                    echo "     | English - en   | Russian  - ru  |"
                    echo "     | Hindi   - hi   | Japanese - ja  |"
                    echo "     | Arabic  - ar   | Punjabi  - pa  |"
                    echo "     |________________|________________|"
                    echo ""
                    exit
                    ;;
            [0-9]*)
                    # It is probably a number, so work normally
                    COUNT="$1"
                    ;;
            *)
                    echo "Unrecognized argument: try 'ipsum --help'"
                    exit
                    ;;
        esac

    fi

#-----------------------------------------------------------------Calculate Entrophy
    if [ "$ENTROPY" = true ]; then
        # Equation = log_2( #_of_options * #_of_languages ) * #_of_words
        log_base_2=`echo "l($total_options*$NUM_LANGUAGES)/l(2)" | bc -l` # log base 2 of options
        entropy_bits=`printf "%.*f\n" 2 $log_base_2` # bits of entropy per word
        total_entropy=$(echo "$entropy_bits * $COUNT" | bc)
        echo "$COUNT word(s) from $NUM_LANGUAGES language(s) produces $total_entropy bits of entropy."
        echo ""
    fi

#-----------------------------------------------------------------Make $COUNT Random Words
    while [[ "$X" -lt "$COUNT" ]]; do
        random_number=`echo "$(od -N3 -An -i /dev/urandom)*$non_random_words/$MAX_INT" | bc`
        WORD=$(sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS)
        # Clean and Format
        DEL="'s"
        WORD=${WORD%$DEL}
        DEL="'"
        WORD=${WORD%$DEL}
        # Clean out 'funny' words (ie proper nouns)
        case ${WORD:0:1} in
            [[:lower:]])
                    # Lowercase indicates a common noun
                    if [ "$LANGUAGE" = true ]; then # If lang was specified use trans
                        random_index=`echo "$(od -N3 -An -i /dev/urandom)*$NUM_LANGUAGES/$MAX_INT" | bc`
                        LANG=${LANGUAGES[random_index]}
                        trans -b :$LANG $WORD 2> /dev/null
                        echo "   ^ $LANG for $WORD"
                    else # else just given normal word
                        echo "$WORD"
                    fi
                    let "X = X + 1" 
                    ;;
            *)
                    # Don't use whatever $WORD was
                    ;;
        esac
    done
}

ipsum "$@"

Origins

The name, Ipsum, comes from Lorem Ipsum the name of filler text for graphical elements of a visual presentation.

  • ipsum.sh, despite it's .sh extension is currently just a shell function, it lacks a first line #!/bin/bash, and a last line ipsum "$@". – agc Oct 5 '16 at 13:31
  • That was intentional, it has the .sh extension for syntax highlighting. I import my functions from my .bashrc so that they are easy to manage. – NonlinearFruit Oct 5 '16 at 13:43
  • The answer above should mention that ipsum() is a function which needs to be loaded first, i.e. . ipsum.sh ; impsum -h. Also, please correct me if I'm wrong, but doesn't .bashrc allocate it's own environmental memory for each instance of bash? If that's the case, then running several shells (in different tabs of a GUI terminal emulator) would load several redundant instances of ipsum(). – agc Oct 5 '16 at 14:01
  • @agc I'll edit it. You are correct that it is a little wasteful, but I like the ease of setup and I also like the ability to easily organize. – NonlinearFruit Oct 5 '16 at 14:38
1

There are a few resources to help you generate random pass phrases, though you might have to take a few additional steps yourself to combine dictionaries or visualize entropy.

This simple bash script will pull your /usr/share/dict/words directory as the population of eligible words. You can specify how many random words and use your own word file. http://linuxconfig.org/random-word-generator

Take a look at this script as well, which provides a few more easily configurable options, like minimum and maximum word length: http://stackoverflow.org/wiki/Dictionary-based_random_password_generator

Heck, for further inspiration, check out this short discussion over on SO about writing such a script in Python: https://stackoverflow.com/questions/18834636/random-word-generator-python

Hope that helps!

Edit: Note that I'm not versed in whatever pseudo-random processes might be used behind the scenes in Python or Linux, so I can't comment on any possible vulnerabilities on that end.

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.