genpass, yet another stateless password generator

07 Jan 2016

Since some time I’ve realized I’m pretty bad at memorizing strong passwords, as a result I’ve been using an unique moderated strong “master” password and I’ve derived others by using a shell alias:

$ alias getpass='_getpass() { _g=$(printf "%s" "${*}" | \
    md5sum | openssl enc -base64     | \
    cut -c1-20); printf "%s" "${_g}" | \
    xclip -selection clipboard 2>/dev/null || \
    printf "%s\\n" "${_g}"; }; _getpass'

I knew than the resulting passwords weren’t really good at keeping my master password secure, after all, md5 hashing is extremely fast and with known collision problems, even worse, I didn’t even iterate over it. So I keep it in secret till I had the time or willingness to use an informed solution. During the last month I’ve been reviewing the state of art of password generation schemes and found than some derivation functions have been designed specifically for this task. So I converted the shell alias to a C program and genpass is the result.

Genpass is by no means original, however when looking around I found than most password generators were plain broken, most of them were iterating fast checksum functions, md5, sha1, sha512, etc, or the ones using either bcrypt or scrypt used hard-coded parameters which could make them vulnerable to future computers. Using a slow key derivation function is as practical as the user is willing to wait, so often more secure default parameters aren’t used because it would make the derivation painfully slow. Fortunately some smart guys have found this problem before and have suggested to use a cache key to accelerate the process for legitimate users. That’s what genpass uses to propose the following paranoid defaults.

Parameter Value
Cache cost (Scrypt N) 2^20
Cost (Scrypt N) 2^14
Scrypt r 8 bits
Scrypt p 16 bits
Key length 32 bytes, 256 bits
Encoding z85

It’s still convenient to use your own parameters, as the default settings will change as computers get updated on CPU/RAM.

Usage

The first time to be executed it will take a relative long time (a couple of minutes) to get back. It’ll create a cache key and will save it to ~/.genpass-cache (this path can be customized), then it will combine it with the master password and the site string to generate the final password, which can be in several encodings (z85 by default). The cache key file should be guarded with moderate caution, if it gets leaked possible attackers may have an easier time guessing the master password (although it still will be considerably harder than average brute force attacks). Later invocations will be instantly (taking on average 0.1secs). This way the scheme strives for the best balance between security and usability.

I’ve also added a getpass wrapper which paste the resulting password to the system clipboard and sets a timeout (10 seconds by default) after which the password is removed.

Installation

Ubuntu based systems (LTS)
$ sudo add-apt-repository ppa:minos-archive/main
$ sudo apt-get update && sudo apt-get install genpass
Other Linux distributions, static binaries
$ sh <(wget -qO- s.minos.io/s) -x genpass
From source
$ make

That’s it, happy password generation 😋

References