
PwdHash (2009) - boredgamer2
https://crypto.stanford.edu/PwdHash/
======
tptacek
This was one of the first "deterministic password managers", which has become
a whole species of side-project password managers. The major practical win for
deterministic password managers is that they're ostensibly stateless; you only
need to synchronize some very basic configuration information to make them
work consistently. In practice, not so much: passwords need to be changed, or
revoked, or customized. You should just use "pass" (or 1Password if you want
something professional).

An interesting thing about PwdHash is that they observed how you can use site-
specific authentication behavior to break phishing, something that
U2F/Webauthn tokens also accomplish.

~~~
tialaramex
One non-obvious thing I really like about WebAuthn compared to PwdHash here is
what happens when bad guys trick you into trying to give them credentials.
I've now implemented all this manually so that gives me more experience of the
unhappy paths which obviously are hard to test on somebody else's site (if you
don't want to risk getting banned).

Imagine you're signing into [https://fake-google.example/](https://fake-
google.example/) having been tricked into believing it is Google but with
various different types of credentials:

* With a memorised password or similar strategy, you give them your actual Google credentials. Game over, you lose.

* With password managers you _might_ realise there is something wrong because it doesn't auto-complete. But you might (for various reasons) give them your Google credentials, after all you've been tricked into believing this is Google. Game over, you lose.

* With PwdHash you give them PwdHash(Google Credentials). Reversing that to find your Google Credentials depends on your entropy choices. For good passwords you win, but most user passwords mean you lose if the bad guys put work in.

* With most "Second Factor" designs including SMS, TOTP, and many dongle designs you give them the second factor and again, you lose if the bad guys planned for this.

* But with WebAuthn its "cookies" (which bad guys can get from the real Google by presenting your username) are themselves site specific. Your FIDO authenticator needs a cookie, and it will implicitly need the cookie to match the rpId, your browser insists the rpId must match the origin FQDN of the web site (fake-google.example in this case) but that won't match google.com so the authentication cannot succeed. You cannot give the bad guys your Google credentials even if you really want to, maybe short of sending them the actual authenticator itself.

[ Do not UPS your Security Keys to bad guys. I think even my deceased
grandmother could have figured that out, if I read stories about people being
successfully tricked into doing this I may despair about our species entirely
]

~~~
whatshisface
> _if I read stories about people being successfully tricked into doing this I
> may despair about our species entirely_

You can't think in terms of "does happen" and "doesn't happen," you have to
think in terms of "90% chance," "10% chance," "1% chance..." and so on. So
many times I have seen people reject good measures by giving an argument to
the effect of "Your system has a 1% chance of failure, which in my brain is
stored as 'can fail,' so it's not an improvement over the old system that
fails 30% of the time, which is also stored in my brain as 'can fail.'"

------
Spivak
This should just be how websites work. I see no reason that a site should ever
transmit the user's password over the wire.

When you create a password send the client a salt, hash their real password
client side, and send the hash over the wire. Treat it as you would their
actual password and salt/hash it again.

Then when the user wants to auth send the client the salt you have on file for
them^ and repeat. Bam. A domain specific password for every site even for
someone who who reuses passwords.

^ inb4 "this creates another 'step' when logging in." Users will type their
username and pw before they get the salt and the client will handle the rest.

~~~
jedberg
What do you gain with the extra hashing on the client side?

The attack you're protecting against is a compromise of the server's password
database. If the attacker has that, then they have the client side salt too.

~~~
toast0
Hashing on the client side prevents the server side from logging the plaintext
password anywhere, and from intermediaries from seeing the plaintext password.
Replay of the hashed value is still possible, without other measures.

Hashing a second time on the server protects from a database leak being used
to access the site.

~~~
jedberg
> Hashing on the client side prevents the server side from logging the
> plaintext password anywhere, and from intermediaries from seeing the
> plaintext password.

No it doesn't, because all of those attackers have access to the client side
salt which is sent to the client in the clear.

~~~
toast0
They would have the client side salt and the hashed password.

Now, depending on the hashing algorithm, maybe it's easy to turn that back
into the plaintext, but with a competent hash, it's not expected to be easy.

Edit to add, if the site does it in javascript, of course they (or
intermediaries) could decide not to do it, or to also pass the plaintext with
the hashed version. That's a separate issue.

~~~
jedberg
If you have the salt and the hashing algo, it's trivial to build a dictionary.
If the password is good enough to not be broken by a dictionary attack, it was
good enough without all the extra hashing.

~~~
Cicero22
Having to mount a dictionary attack which may fail/ take an indeterminate
period time seems like a win. Albeit only for users who reuse the same, strong
password.

~~~
jedberg
Exactly. And if they’re using a strong password already than you haven’t
gained anything.

The dictionary attack on the client created hash and the attack on the server
hash of the plaintext take the same effort.

~~~
Cicero22
An eavesdropper who overhears a password just has the password, but an
eavesdropper who overhears a hash and a salt now has to run a dictionary
attack which might only have a 99% chance of recovering the password.

In the first case, there's a 100% chance of the password being compromised,
but in the second an attacker has to spend resources on cracking a password,
and there's still a small chance that they're unable to crack it. The second
case seems like a clear winner (I could still be missing something).

~~~
jedberg
You're technically correct, but if they have access to the plaintext
conversation, they can just steal the cookie that comes back.

So sure, you may have prevented the release of a reused password, but you
haven't prevented anyone from impersonating your user on your site.

Depending on how they have access to your plaintext conversation, they could
get your reused password from another site.

In other words, while this might make a slight difference in the stealing of
reused passwords, it's not really worth the effort. There are far better
solutions, like encouraging the use of a password manager.

~~~
Spivak
> but you haven't prevented anyone from impersonating your user on your site.

That is the whole point. In this system the hash generated on the client is
literally your password. It's just to provide some extra protection for people
who reuse passwords that are compromised on the server or over the wire.

>There are far better solutions, like encouraging the use of a password
manager.

That might be better but your solution requires telling billions of people to
not reuse passwords and use a password manager. Or you could implement this on
your site and your users are instantly better off. Real users are better off
if we just make their behavior safer.

~~~
jedberg
But it only helps real users in the rare case that someone has already
compromised the secure connection between their computer and your server.

That's not a realistic use case if you use https on your site.

The effort in implementing this, testing it, testing fallbacks when Javascript
is unavailable, testing every change with the fallback on and off, and so on,
just isn't worth it for that absolutely tiny gain.

------
sisk
Used this extensively before password managers were abundant—even wrote my own
bookmarklet for it ~10 years ago[0]. One thing to be mindful of: login URLs
can and do change. When this happens, unless you can recall the hostname,
you're completely out of luck.

[0]:
[https://gist.github.com/jasisk/fc0283e84814c696d3cd](https://gist.github.com/jasisk/fc0283e84814c696d3cd)

------
627467
What a coincidence as I'm reading up on deterministic password generators:

\- DPG: [https://plevyak.com/dpg.html](https://plevyak.com/dpg.html)

\- MasterPassword: [https://masterpassword.app/](https://masterpassword.app/)

\- LessPass: [https://lesspass.com/](https://lesspass.com/)

I like the idea of such mechanism for my passwords, but I feel like having to
enter a masterpassword so often actually poses as a vunerability. The password
managers I currently use, normally enables me to use fingerprint or leaves
some minutes before timing out so that I don't need to enter my master
password as often.

One idea I'm having is to combine the deterministic and stateless aspect of a
simple js generator, with a simple db that user can maintain with a online
spreadsheet:

1.this db would store states for the calculator that user would need to
manually re-enter, and it's URL would be only known to user (say a Google
sheets, json URL)

2\. This URL would be stored for limited time on browser cache improving UX
for short period of time.

3\. The db itself won't store secrets, just "metadata"

~~~
polm23
I've been using PasswordMaker for years for this and been quite happy with it.

[https://passwordmaker.org/passwordmaker.html](https://passwordmaker.org/passwordmaker.html)

On Chrome the extension you want is PasswordMaker Pro (not paid, it's just a
name). It allows you to save profiles for different domains and saves them
wherever it is Chrome extensions save data.

------
xwes
SuperGenPass[1] is a refinement of this idea. The code itself has been dormant
for years[2], but the bookmarklet and mobile web versions still work great. In
fact, adding the mobile web page to my iPhone home screen with Safari makes
this a pretty straightforward way to make passwords accessible on mobile
without worrying about syncing.

1:
[https://chriszarate.github.io/supergenpass/](https://chriszarate.github.io/supergenpass/)
2: Since 2016 :(
[https://github.com/chriszarate/supergenpass/commits/master](https://github.com/chriszarate/supergenpass/commits/master)

------
blakeross
This is definitely pre-2009, I built this at Stanford w/ the others and I was
only at Stanford until around 2005. (But they may have continued updating it
given the Firefox version number referenced.)

~~~
29athrowaway
Hey man, totally unrelated but: kudos for your work on Mozilla Firebird (now
Firefox). I can't believe you were like 16 or 17 at the time.

------
gregmac
I haven't yet decided how I feel about this vs a full password manager (with
unique passwords per site), but do kind of like the idea there's no
account/vault: literally the entire usage is via a single password.

I have a suggestion to greatly increase usability:

Right now, as the owner points out, this relies on using a password starting
with @@ to trigger this mechanism (which is a usability issue), and relying on
the user entering their passwords into the web page (which is a phishing
danger).

Given this already requires a browser extension, move the password to a UI
within the extension, and instruct the user not to ever enter their password
anywhere else (on why page directly). Use a button in the browser extension to
trigger filling in the site-specific password. This avoids phishing the main
password, avoids the @@-prefix requirement, and the extension could now also
cache the password for some amount of time so the user doesn't need to re-
enter it.

Interesting idea/project nonetheless.

Edit: oops, just noticed this is from 2009. I noticed lack of Chrome but not
the ancient browser versions! Did this go anywhere?

~~~
Hello71
similar ideas have been around for ages. for the most part they are unpopular
because they have a number of severe usability issues: SSO sometimes uses
multiple domains, password rotation requires either changing all passwords or
memorizing a per-site generation, multiple entries per site requires
memorizing a per-site key...

------
freedomben
This reminds me of PasswordMaker[1], a neat tool that you can easily self host
(or run offline from your filesystem) and customize. The basic idea is that
you don't have to store any passwords, but you can still easily have a
different one for every account. You generate a hash based on the
domain/hostname and the master password.

It worked really well for a long time, tho eventually I ran into enough corner
cases that I had to switch to a traditional password manager anyway. I still
use it for some stuff however.

[1]:
[https://passwordmaker.org/passwordmaker.html](https://passwordmaker.org/passwordmaker.html)

------
senderista
This is equivalent to hashing passwords using a global public salt (the domain
name). If it became popular enough, you could mount a trivial offline
dictionary attack on popular passwords.

------
sm4rk0
This creates longer password even with a short master pass:
[https://ss64.com/pass/](https://ss64.com/pass/)

------
potiuper
[https://en.wikipedia.org/wiki/Salt_(cryptography)](https://en.wikipedia.org/wiki/Salt_\(cryptography\))
(1970)

------
correct_horse
This would break if the site owner changed their domain name, or more likely,
they have multiple domains that redirect to the same IP address. Is that a
serious flaw?

~~~
tialaramex
It's a problem certainly.

To be fair that would also be a problem for many automated or semi-automated
password managers. I have PassFF for example and it's currently suggesting the
password it knows for news.ycombinator.com, I think it would guess that
hacker-news.ycombinator.com should also suggest that, but if this site moved
to [https://hacker-news.example/](https://hacker-news.example/) I'd need to
make the connection in my head to retrieve the password.

One important thing compared to WebAuthn, which has this behaviour built into
it, is that the site owner doesn't know you use PwdHash and so their testing
won't discover this problem, indeed they might insist it isn't a problem at
all because it isn't part of their mental model of password behaviour.

Whereas in WebAuthn it just doesn't work, so even fairly light acceptance
testing would discover that the new site can't re-use old WebAuthn credentials
and that's a problem.

------
acqq
Needs year in the title: (2009)

~~~
zokier
I think it's more like 2005

~~~
floatingatoll
Firefox 3.5 was dated 2009 and the page references it, so that's the latest
verifiable date of activity that I can find (and I missed it except for the
above comment).

~~~
tehlike
Archive.org shows 2004.
[https://web.archive.org/web/20040507195550/crypto.stanford.e...](https://web.archive.org/web/20040507195550/crypto.stanford.edu/PwdHash/)

That's the oldest it goes for this site.

~~~
floatingatoll
The date isn't "when was this first ever posted on the internet", it's "when
was this last materially updated in a relevant manner".

