Announcing Vault: safer passwords for the web

TL;DR: This is something of a rant. The important bit: I’ve built an open-source storage-free available-anywhere secure password generator called Vault. It’s available online and for your terminal.

What with recent weeks being a pretty bad time to be a LinkedIn, eHarmony or Last.fm user, I’ve been putting the final touches on something I hope will make it much easier for Internet users to keep their accounts safe. But before I dive into that, let’s review the problems users are facing right now.

Anyone who uses the Web is likely to have signed up for a few, maybe dozens, maybe hundreds of online services, covering a range of applications from sharing pictures of kittens to storing all of one’s money and personal information. Many of these accounts are identified by the user’s email address, and most people use the same password for every service they sign up for, because that’s what’s easiest (and often because nobody told them not to). So while technically all of your data is in nice little silos, a breach of one service provider’s database can often lead to the attacker gaining access to accounts on lots of other services. People aren’t attacking eHarmony because they want to know your ideal date – they want your email password, because that’s the key to everything else. The money in your bank, the marketable information Facebook knows about you, your whole identity.

So, the sensible thing to do is use a different password for every service you use. Then when one site’s database gets stolen, none of your other accounts is at risk. Well, sort of. How true this is depends on how good you are at picking passwords. Actually, that’s a lie. It relies on you not picking passwords: the best way to make sure that one database leak doesn’t lead to others is to use completely uncorrelated passwords, i.e. get a random number generator to pick them for you. Passwords chosen by people are highly likely to follow some predictable pattern, or include affordances for memorability that make them easier to crack.

But random passwords have a problem: they’re not memorable. This is actually a good thing for security but it makes them hard to use safely. Advice for dealing with this ranges from writing your passwords down (a horrible idea) to using a password manager like 1Password, KeePassX or LastPass to store your passwords in an encrypted database locked with one master password. Unfortunately most people still don’t know about these tools and so you end up with break-ins caused by someone leaving their password on a post-in note stuck to their monitor.

While these tools are useful, and certainly much better than using the same password everywhere or writing them down, I think they still suffer from a number of problems, namely: adoption, security and portability.

All these tools require you to install something on your various devices. They typically consist of an application that manages storage of passwords, a random password generator, and maybe a browser plugin and syncing support. Some of them also require payment. And while I don’t begrudge anyone trying to make money from software, it must be recognised that all of this creates friction that makes it less likely any given person will adopt the product. Less adoption means more unsafe accounts out there, creating more potential for break-ins. Trading off security against convenience is a very hard problem, but I think we can make people substantially safer than they currently are, with far less ceremony than these tools involve.

The second problem is security. While a good password manager will use a sensible encryption scheme to protect your data, it’s worth questioning whether storage is necessary at all. Any sensitive stored information requires very careful treatment when it is stored on disk or transmitted over a network; the safest data is that which is never stored anywhere and exists only in someone’s head.

(While I’m on the topic of storage, it’s worth pointing this out to service providers: because everyone uses the same password everywhere, if you run a site that requires people to log in, you have their email password. I don’t care if all your site does is let people rank versions of that one picture of a fishing boat on the beach at dusk that everyone seems to love – you have people’s email passwords and you had better take damn good care of them. This means hashing them using an expensive salted hashing algorithm like PBKDF2, Bcrypt or scrypt with a tunable work factor. It should take well over 100ms to hash someone’s password, more if you’re using a slow programming language. It must be computationally expensive for someone to guess a single password; using hashing algorithms designed for speed makes it easy for anyone to brute-force your passwords. I have, worryingly, seen several people advocate rate limiting or IP blocking on your login system for this purpose. This is completely useless: the most productive thing for an attacker to do is not to guess username-password pairs through your login form, where a round-trip takes at least 10ms, but to steal your whole database and analyse it on their own hardware. Your rate limiting does nothing to stop this, and the expense of guessing a password must be baked into the hashes themselves.)

Anyway, where was I. Right, password managers, yes. The third problem with password managers is partly a consequence of the storage problem: portability. Password managers have two factors conspiring to make them less portable: they require software installation and so must provide versions for every platform they wish to target, and they must provide a way to make your password data available everywhere you need it. I’ve seen too many products (‘too many’ can mean ‘one’ if it’s something you really care about) do an ‘experimental’ Linux release and then abandon it – I don’t trust that it’s going to continue to be worth any company’s time supporting all the platforms I need to have my passwords available on. And portability doesn’t just mean availability on all my devices. What if you’re travelling, or out without your phone and you need to pop into an Internet café? What if your password manager simply doesn’t work on your phone? What if your password manager doesn’t provide online retrieval, or it’s down for maintenance? You’re stuck.

So, you can’t use the same password everywhere, creating good passwords is hard, bad password policies make it even harder, and password managers suck. But, back in December I found a good idea in the aforelinked article:

I generate a different password for every service, based on a convoluted master password and the name of the thing. I do this because it’s what you’re supposed to do; it’s what security nerds (including myself for the purposes of this post) tell everyone else to do. “Ho ho!” we all chuckled to ourselves after the Gawker leak, and the subsequent breakins to various other things that used the same passwords. “If only these chumps had been generating different random passwords for every service!”

So my passwords look like 'fC`29ap5w78r3IJ, or Ab3HE4 2Iv5hJk\K, or mw@\_h< ~o04neHiJ{. Those are actual examples i just generated. I’m eating my own dogfood, so to speak.

Fuck Passwords

Now remember the qualities we want from our passwords: different for every site, and uncorrelated. The word ‘uncorrelated’ is usually taken to mean ‘use a random number generator and store the result somewhere’. But we can get passwords that look random (technically, this means there’s no polynomial-time algorithm that can distinguish them from genuine random noise) in a deterministic way: a function that produces random-looking output but gives the same result every time if given the same input. We can just use hashing functions for this: their output is pseudorandom, deterministic, and changes drastically if the input is slightly changed. This means we can generate a set of random-looking passwords from one master passphrase and a string that’s different for each service we use, and because it’s deterministic we don’t need to store the result anywhere. This means we can put up a static web page that implements such a function, never stores or transmits the user’s data, and is available everywhere and hostable by anybody.

So that’s what I’ve built. A simple page that takes your master passphrase and service name, and generates a very strong password from them. It lets you select which characters are required/forbidden, to work around sites with bad password policies. It has a command-line version based on Node.js. And, needless to say, it’s open source and anyone can host a copy of it.

The core idea of Vault is that it works without storing anything by default. This means no installation, no storage to secure and sync, and total portability: it’s just a static web page instantly accessible from anywhere. You can host your own copy for when my site’s down, put a copy on your laptop or internal network, whatever you want. The storage options offered by the command-line version are simply a convenience: I can get my Gmail password by typing vault gmail | pbcopy, but if I’m on another machine without my stored settings I can still get my password from the web version. I am currently investigating ways of providing similar convenience on the web, but until then you can do something quite easy: write your character settings down. The character constraints of websites’ passwords are public knowledge already, there’s nothing dangerous about keeping a note of them in a text file or in your wallet.

But, I hear you cry, how does this protect anyone? Can’t an attacker just use Vault themselves to pre-process my password before trying it? Yes, of course they can, but they could have just tried your password before, so they’ve not gained any new power. Vault protects you in two important ways. First, the passwords it generates with the default settings have about 130 bits of entropy (20 characters from a uniformly distributed 94-character alphabet). This is far higher than a dictionary-word password, making it resistant to brute-force attacks, in fact zxcvbn estimates they will take billions of times the age of the universe to crack by brute force. Second, the fact that a set of Vault passwords looks entirely random means that if attacker gets one of your passwords they cannot predict any others or discover your master passphrase. This is especially true if you include your username in the the service name when generating a password so you get a universally unique password. Plus, it gives you the freedom to choose a good master passphrase rather than being constrained by the awful password policies affecting many websites.

I’ve been using this system for six months now, and the generator algorithm has been through several rounds of design improvements to the point where I’m now happy calling it stable and freezing it. (I’d go into how it works but I’ve already rambled on for 1700 words so I’ll save that for another post.) Initial response from the few people I’ve shown it to has been really positive, and I’d encourage you to try it out if you’re still using one password everywhere. Read the FAQ first before diving in.

I’ll close by saying that I’m absolutely not trying to compete with the non-password-based authentication systems that are coming out. I really want BrowserID to succeed and kill passwords for good, but we’re not there yet. I’m just trying to do something that works with the web as it is today, that’s reasonably secure while still being extremely convenient, and is much better than what the majority of people do with their passwords. It’s a stepping stone until we have something better.

If you've enjoyed this article, you might enjoy my recently published book JavaScript Testing Recipes. It's full of simple techniques for writing modular, maintainable JavaScript apps in the browser and on the server.