Master(ing) Passwords

Good passwords should be only known to you, they should be hard to guess, you should have different ones for each service and you often need to change them. Meeting all these requirements is hard and people often fail.

Some people claim that biometrics (like finger prints, facial recognition or iris scans) can help you out of this misery, but they are wrong. You can’t keep your face (and even your finger prints) private. Worse, you can’t change them if someone starts to misuse them. So they can, at best, be used as a kind of user name.

You can use password safes to store complicate passwords for all the web service you use. But your app may use a proprietary container format. What do you do if the app becomes obsolete and all of your passwords are stored in a format no other software can read? And can you really be sure that no one can read your passwords that you uploaded into the cloud?

A relatively new approach to solve this problem is the Master Password algorithm by Maarten Billemont. Its basic idea is strikingly simple: You have one (complicated) password that you have to remember. Based on that password, the algorithm generates site or service specific passwords of any complexity – ranging from four digit PINs to 20 characters long all-random passwords. Given the same input, the algorithm always generates the same passwords. Since there’s only one secret involved in the whole process (your master password that you keep in your head), no passwords need to be stored anywhere and yet you can use Master Password from all your devices if you have an appropriate app available.

I read about the Master Password algorithm in August 2014 in the German IT magazine c’t and got curious how hard it would be to implement the algorithm in Python (3). It turned to be quite straightforward. After toying around with it for a while, I have now a relatively stable and useful master password library and, on top of it, a command line interface.

Available implementations

Before I go into detail about it, I want to list all available implementations I’m aware of (please contact me if I forgot one):

  • Alternative implementations:
    • Master Password for Android: An alternative Android client with a nicer GUI (in Lollipop’s Material Design). Available as free and pro version in Google’s Play Store.
    • qMasterPassword: A QT based GUI written in C++. It should be platform independent but unfortunately doesn’t provide any binaries. You can grab the source from github and compile it on your own.
    • Chrome Extension: A Chrome extension available in the Chrome Web Store. The source can be found on github.
    • Python CLI and library: My own implementation in Python. It runs on OS X, Linux and Windows. You can get it via the PyPI. The sources are on bitbucket.

As you can see, you can use Master Password on most of the common platforms and devices.

mpw 0.3

After two prototypes, my mpw package has now reached a certain level of maturity and provides some comfort. It’s still labeled as alpha, though, because some features I’d like to implement are still missing.

For your convenience, mpw remembers the sites and users that you created, so the first thing you have to do is creating a user (you can have multiple) and some sites for them:

$ mpw adduser Alice
Enter master password:
Confirm master password:
Added user "Alice".
$ mpw addsite test-site
Enter master password for "Alice":
Added site "test-site" for user "Alice".

mpw stores an scrypt hash of your master key. It will then tell you when you make typos while entering your master password. By default, newly created sites will use the long password type. Run mpw addsite --help to get more information on that. The sites and their settings are stored encrypted on your disk (using cryptography Fernet). Note, that these steps only simplify the later usage and are not required by the algorithm.

To actually generate a password for Alice’ test-site account, run:

$ mpw get test-site
Enter master password for "Alice":
Password for "test-site" for user "Alice" was copied to the clipboard.

As the output suggest, the command copies the password into your clipboard. You can then simply paste it into a login form.

mpw can also print the generated password to stdout. This way you can pipe it directly to other commands like sudo:

$ mpw get -e server-root | sudo -S vim /etc/crontab

The command mpw --help prints a list of all commands that are currently supported.

Here is a list of all available features:

  • Supports multiple versions of the algorithm. If the algorithm evolves, you can still generated password for older sites using an older version of the algorithm. Currently, version 1 and 2 are implemented.
  • Generated passwords are copied into your clipboard by default. You can also print them to stdout and pipe them into other commands.
  • Lets you add, delete and list users. You can set a user as default user and you can change their master password (which will invalidate, by the very nature of the algorithm, all previously generated passwords. Sometimes this is necessary).
  • Lets you add, delete and list sites for a specific user. Settings for a site can be updated.
  • Stores a hashed version of a user’s master key on disk in order to tell you when you made a typo in your master password (which would generate the wrong site specific password). scrypt is used for that.
  • Stores the sites and site settings of a user encrypted. cryptography Fernet is used for that.
  • Can also be used as a library by other programs.
  • 100% line and branch coverage. Multiple tests to make sure it generates the same passwords as the reference implementation.
  • Written for Python 3.4 and above.

And these things are planned for the future:

  • Add import and export functionality ((un)encrypted JSON and the format that the OS X app is currently using).
  • Allow the generation of login names.
  • Allow the generation of answers for security questions.
  • Maybe a GUI using PyQT that runs under OS X, Linux and Windows. But since there are already plenty of GUIs and I don’t have that much time, I may not do it. Please contact me if you are interested in helping me out here.

You can grab your copy of mpw from the Python Package Index. I recommend installing it via pipsi:

$ pipsi install --python `which python3` mpw

But you can also use pip to install it globally or into a virtualenv:

$ pip install mpw

Warning: If you already used mpw 0.2 and have some sites configured, run this script to upgrade you config file. Run it after you installed mpw 0.3 but before actually using it.