4 fatal flaws in deterministic password managers

Wouldn’t it be nice if your password manager didn’t need a database? Instead of synchronizing a password vault between your devices, you could use the magic of cryptography to magically transform a master password into a unique password for each site.

There have been a numerous and ever growing implementations of this idea. Much of the marketing material for these tools talks about how using a deterministic scheme allows “sync-free” operation, is “more secure” than a password vault, and often that it’s a newer idea than encrypted password vaults.

In this post, I will argue that you can’t practically provide “sync-free” operation without making your password manager unusable, how using a deterministic scheme harms security, and how it’s actually an old idea which never caught on for good reasons.

Deterministic password derivation schemes date back to at least 2003: Stanford PwdHash and SuperGenPass are two early examples (If you know of earlier ones, I’d love to hear about them). These tools pre-date most modern password vaults, but never evolved into the sort of practical tools that the latter did.

Edit: I have been informed of at least one scheme that predates Stanford PwdHash and SuperGenPass: Alan Karp has informed me his Site Password scheme dates back to 2002. More information on it is available in the Site-Specific Passwords HP Tech Report.

Why is that? Let’s take a look at their flaws.

Deterministic password generators cannot accommodate varying password policies without keeping state #

One of the big selling points of deterministic password generators is that they enable “sync-free” operation: you can derive all the passwords for the sites you use from the master password alone, so there’s no state that needs to be synchronized between devices.

Unfortunately, sites have wildly varying and often conflicting password requirements: non-alphanumeric symbols are mandatory! Passwords must be alphanumeric only! Capital letters required! Passwords must be lower-case only! Passwords must be at least 12 characters long! Passwords must be at most 8 characters long!

While many of these requirements seem silly and in a perfect world all sites would adopt the new NIST password guidelines, reality is messy and there is no single deterministic password generation scheme which can accommodate the password policies of all sites.

The most common solution to this problem is to abandon “sync-free” operation and keep some state about tweaks to the password generation scheme which produce passwords that meet the policy for a specific site. Unfortunately, by doing so we lose the #1 selling point for these schemes, and now have state that needs to be synced between devices.

There are other solutions which do remain stateless at the cost of user experience: users can be asked to tweak the generated password to meet the policy every time they log into a site, and hope they can remember the exact settings. I consider this unacceptable from a user experience perspective.

Some authors of deterministic password generators argue that synchronizing “tweak” data is superior to synchronizing the ciphertext of a password vault, because the ciphertext is somehow “more sensitive”. If you agree, please keep reading, because at the end of this post I’ll argue the opposite.

The main takeaway of this point: we can’t practically get away with “sync-free” operation without a terrible user experience. The user experience burdens outweigh the benefits.

Deterministic password generators cannot handle revocation of exposed passwords without keeping state #

Strike two against “sync-free” operation deals with revocation: There are many ways we could accidentally expose the password for a specific site: accidentally copying and pasting it into an email, IM, or social media. This is a fairly routine occurrence that happens to the best of us. Another possibility is a security incident that exposes unhashed passwords: this can be anything from a “Heartbleed”-style vulnerability to a site accidentally logging unhashed passwords.

Solving this problem with a stateful password manager is easy: if we’re using a typical encrypted password vault, we just make a new password. If we’re using a stateful deterministic scheme, we can bump a counter associated with the site, and include that counter’s value as part of the derivation scheme.

There’s nothing we can do in a stateless scheme without harming user experience. We could ask the user to remember the site-by-site counter and input the correct counter value to derive the correct password. But I think this is silly.

So once again, we’re stuck with some state to synchronize, and the “sync-free” dream is simply impractical.

Deterministic password managers can’t store existing secrets #

Even if we abandon “sync-free” operation, authors of stateful deterministic password tools argue they’re still beneficial because there’s less data to sync, so therefore they’re faster and more web scale or something like that.

I have a 1Password vault containing thousands of passwords and cryptographic keys. It weighs in at 512kB. I do not see the size of password vaults as a pressing concern.

But beyond that, a deterministic scheme cuts you out of the ability to store data which is not derived deterministically in a password vault.

You can’t store credit card numbers or bank account numbers in such a vault.

You can’t put arbitrary cryptographic keys in such a vault.

You can’t store randomly selected answers to security questions in such a vault.

I consider this to be part of the basic functionality of a password manager. Leaving it out is unacceptable to me.

Exposure of the master password alone exposes all of your site passwords #

The sales material for deterministic password managers often includes some specious reasoning about how they make you more secure than an encrypted password vault, typically making the argument that having any ciphertext at all is some sort of security liability (it’s not; that’s the point of cryptography). But the opposite is true: deterministic schemes have worse security properties.

With a traditional encrypted password vault scheme, we need two things to obtain site-specific passwords: the ciphertext of the password vault, and the master password.

With a deterministic scheme, as an attacker we only need one: the master password.

Under these schemes all it takes to expose the passwords to every site you use is the exposure of your master password. If you accidentally type or paste your master password into email, IM, or social media, an attacker can leverage that alone to derive all of your site-specific passwords.

With a system that uses an encrypted password vault, this is insufficient: an attacker must also obtain the ciphertext of your password vault. This ciphertext acts as a sort of insurance policy: so long as the attacker can’t get to it they can’t leverage your master password to attack you, and getting rid of it is therefore a huge drawback.

Now granted, in either case you’ll probably want to rotate all of your passwords in the event your master password is exposed, just in case. But an encrypted password vault will keep you safer: If you can rotate the master password on your vault, and delete all previous backups and copies of your vault, you’ll be in a lot better shape than if you accidentally expose your master password for a deterministic scheme.

Nevertheless, the authors of these tools use specious reasoning argue they offer better security properties, despite making useless tradeoffs that weaken security. In cryptographic circles, there’s a term for this: snake oil.

A password manager is one of the most important security tools available today: it literally holds the keys to your online existence. For the record I use 1Password as my password manager. I hope if you were considering switching from a traditional password vault to one of these deterministic password managers, you now see the flaws and will avoid them in the future.

Follow-up: Bolstering deterministic password schemes with a pre-shared secret; offline attacks against encrypted password vaults #

NOTE: This section was added after the original publication of this post.

Following the publication of this post, several people suggested sharing a secret included as an input to the password hashing function as a way to bolster the security of deterministic password generation schemes. This sort of additional input to a password hashing function is typically called a “salt”, and although salts aren’t always “full entropy” (i.e. 128-bit uniformly random value) or kept secret, I would agree that a “full entropy” secret salt value shared once between devices should be sufficient to prevent accidental disclosure of the master password from being immediately catastrophic. Unfortunately none of the people making this suggestion could point to an app that actually does this. If you know of one, I’d love to hear about it!

Others pointed out that password vaults are vulnerable to offline attacks if they are e.g. obtained from a cloud service in encrypted form, and cite this as a disadvantage of using an encrypted vault as opposed to a deterministic password generator. This is also true: encrypted vaults are vulnerable to offline attacks. Ideally modern password hashing algorithms shouldn’t be vulnerable to offline attacks (though I would suggest using scrypt or Argon2 rather than the cited “WarpWallet” construction, which I view as needlessly complex and redundant), especially if you choose a strong master password, but offline attacks are still worth considering.

Both these claims were the most common responses to my post, often made by the same people, but for whatever reason nobody put the two of them together and suggested using a full-entropy secret salt stored out-of-band from the encrypted password vault to guard against offline attacks. So I’ll go ahead and suggest that: using this sort of out-of-band, sync-once style secret improves the security of either deterministic password managers or encrypted password vaults.

 
1,119
Kudos
 
1,119
Kudos

Now read this

Rust 2020: towards a 1.0 crate ecosystem

The Rust language itself went 1.0 in 2015. And yet, almost 5 years later, at least in my anecdotal assessment talking to and reading things written by current or potential users, there is still a sense that the language is still in some... Continue →