219 comments

[ 3.5 ms ] story [ 255 ms ] thread
Sounds a good idea. I'd like to see a more technical description of how it derives the public/private key pair from a password. In addition, the language choice of C# is probably going to limit its popularity, given how C# is still tied to Microsoft world (I know they are open sourcing .Net, but that has not matured yet).
"If a user attempts to login to a malicious site accidentally or because they were tricked by a similar but different name, the malicious server will only gain knowledge of a derived public key. The attacker will not be able to impersonate the user at any other server, or even on the compromised server, because the attacker has not discovered either the user's private key for connecting to the compromised server, or the user's password that could be used to derive the private key on this or other servers."

Doesn't this assume a lot about the state of the internet? I mean a phishing attack could easily harvest the user's password, then the attacker effectively has their private key. Unless every user were trained well on how to determine whether the connection can be trusted, but that's still a problem today in 2015 even with https.

No, that's not a problem at all; the key appears to be derived from more than just the password. The only weak spot is if you can run arbitrary code on the user's PC.

(I'm going by the textual description on the linked page as there doesn't seem to be a more detailed or formal one)

The key, as I understand it, is derived from a combination of the password and other deterministic elements, like the host URL. I suppose it's supposed to be ethereal, generated only for the session and the disposed after the user logs out. But for it to work, the user would have to be able to generate the exact same key on other machines using the same password. In which case, all an attacker needs to obtain the private key is the password and the vulnerability to phishing remains.
I think you're missing the fundamental point here - users of this technology will never enter their password online again.

Instead, imagine new HTML elements and you could have

<form type="cbcrypt"> <input type="username" /> <input type="password" /> </form>

and the web browser would allow you to enter your credentials in a secure, NATIVE window. (At least secure from web stuff - keyloggers get a lot more powerful under this scheme.)

If it works as advertised, it's quite nice. Personally, I think this is very close to what we need.

I will note I still probably wouldn't use it because if your password is exposed, then you're screwed. It is very close though. A hardware element or something might mitigate this enough.

Ok, but how would a native window prevent an undereducated user from naively entering their password into an attacker's spoofed login form? In my mind this strategy more or less kicks the ball down the field as opposed to revolutionizing security.
Would this not still be phishable? All an attacker would have to do is make a website look enough like the real thing, then use a plain <form> element and capture the submitted form content.

I would think an out of browser app might work better for that task.

Well, there's always the venerable but little-known <keygen> HTML tag already... :)
If this is traditional public-key crypto, having the password does nothing for the attacker without the private key. But I didn't watch his "technical details video" so I don't know what he's actually implemented. He mentions that getting the user's password would allow you to derive the private key, which makes no sense.
That's exactly the problem. The private key and the password are effectively 1-1. So if you can phish the password, you have the private key. This solves nothing.
I still don't understand the model, then. How the hell do you derive a private key from a password?
The hard part is getting browsers to all implement something like this (all with the same specification), which for some reason hasn't been happening, despite the fact that a mechanism like this is an obvious design that is obviously better than sending passwords.
(comment deleted)
Browser support would be better, but sites could already implement it in JavaScript.
That would destroy security, since a compromised server could now get your password by serving malicious JavaScript...
Can't a compromised server already get your password by serving malicious JavaScript?
A malicious server doesn't need malicious javascript to do it, it already receives the password in the plain, but that is what is trying to be mitigated in these efforts.
So you agree that a js lib would be an improvement over the status quo?
Using a JS lib would not mitigate any risk here unless the compromising of the server that hosts the JS is separate from the compromsing of your web server.
It mitigates passive MITM attacks, for one.

On the other hand, there's nothing that's made _worse_ by choosing to do it that way. Plenty of things that are the same, some things better, but nothing worse.

Hardly - if you are not using HTTPS in the first place then sending the hash across the wire instead of the password are the least of your worries.
It's been done, most notably in IBM/Lotus Notes, but that also brings its own set of problems to the table.

In the Notes system, the user has an encrypted local credential store (part of the ID file) which contains, among other things, the user's private key and any shared secret keys the user may have been granted. The ID file also contains (in the clear) a certified public key, user name, and other information that should not be considered secret. The only password authentication is locally with the ID file. The password is salted and stretched with a key derivation function; the derived key is used to attempt to decrypt the encrypted portion of the ID file. "Success" is determined entirely by padding and checksums. Neither the password nor any variation on the theme of a hash of the password is stored anywhere. The "safe" portions of the ID (username and public key) are used to create a user account on the server.

Authentication proceeds much like this: "Hi, server! I'm this guy according to that guy." "Oh yeah? Well, this guy (if that's your real name), you ought to be able to answer this encrypted question and send me a signed response."

(Determining whether that guy actually vouched for this guy is standard signature stuff, assuming the check is needed at all. For stand-alone clients, a locally-generated certifier is SOP.)

That does raise a couple of potential pain points, though. One is simply managing the local store, making sure that the users always have access to their credentials. Another is that when a store dies, the private key dies with it (secret keys can always be re-issued to a new credential store once the user is satisfactorily vetted). And users have this horrible, horrible habit of either never backing anything up or "backing up" to the same physical medium. In the corporate Notes world, that's not such a problem since updated ID files mail themselves off to an ID vault, but who gets that trust in the civilian world? And there's the little matter of password recovery (in Notes, a KDF state accessible using a combination of something like Shamir secret sharing and the private keys of k of n trusted administrator IDs) — one probably doesn't want to throw recoverable credential stores into the wild hoping that trust is never broken. Without password recovery (which isn't actually password recovery; it simply allows the user to re-encrypt the I with a key derived from a new password they choose) of some sort, anything that requires your private key is lost when your password is lost. Automating the resetting of a server account brings us back into the realm of highly insecure things like "security questions" (since it's very likely these days that the second factor of 2FA is the same lost/stolen device that prompted the need to reset the account in the first place).

Nothing's perfect... or easy.

Throw a password on SSL/TLS client certificates and you have something that sounds about the same. Nobody used it because it was confusing to users.
Password on an x509 cert requires the x509 cert to be stored or made available to the client somehow. The whole point of CBCrypt is to allow password authentication and encryption without the user needing to change any behavior or learn anything.
"CBCrypt deterministically generates a public/private keypair unique to each specific user, on a specific server, using a specific password. Any variation of any of these factors results in an entirely different and unrelated keypair."

If it deterministically generates a keypair from a password, then attacker acquiring a public key is equivalent to acquiring a password hash — the public key now becomes a verifier.

"The worst attack a malicious server can mount is an expensive brute force attack, attempting to overpower the rate-limiting function and eventually guess a password that recreates the exposed public key."

Almost the same result as if the server just stored an scrypt hash, but more complicated, and without a random salt. The solution for the problem just makes it worse.

Not quite - a malicious server would receive the plaintext password in the current status quo.
You could scrypt on the client.
You're still passing the output to the server, which can be repeated. Certainly better than just a password, but not as good as public key crypto.

In the end, I'd probably prefer something like SRP

(comment deleted)
> You're still passing the output to the server, which can be repeated.

Not if the server generates a unique ID for each attempt, and that ID must be used in hashing. It can be as simple as a timestamp.

Which is then going beyond just using scrypt on the client. What you explain is simply challenge-response authentication.
If a server just wants a hash, then that hash becomes the password. MITM attacks still work as long as all server credentials are public. EX: A fake wifi hotspot wants to MITM a connection and can fake any public information (public key's, IP's, DNS, etc.)

Further, a fake website can sidestep this by not using a secured connection and just faking the UI.

If you read the mechanism, you'll see that this involves more than a site faking the UI - it requires browser integration. This mechanism does not protect a single site, but rather the ability to pivot from one site to another with the same password or key. You also breeze over "can fake any public information" - I have no idea what you are trying to say by the ability to fake public keys - that is not really a thing. HTTPS rides on having a trusted intermediary and so even a malicious MITM couldn't simply fake a public key.
You run into the question, is this the 'magic' UI or a PNG send from HAXORU.

Windows reserves CTRL + ALT + DEL for this reason, but doing that on a tablet / phone that's already in production quickly runs into issues. Also, windows had plenty of issues with fake login screens.

PS: I suspect protecting people from such things ends up requiring fairly strong AI or significant compromises.

The difference here though, is that the private key is not being sent verbatim to the server.
(comment deleted)
It's not the same. The main point of asymmetric ciphers is that it's a very good way to prove I know something without ever revealing the thing I know.

Instead of sending the public key every time, the server sends a challenge, which only the private key holder can answer. This is a pretty basic usage of keypairs and an extremely brief perusal of their source code suggests to me they've thought of it.

So no, the public key is not the password, unlike hash based systems which do suffer from the problem you're concerned about. The hash IS in fact now your password in those systems.

Can you explain in more detail why you believe the public key "isn't the password" the way it is in a "hash based system"? I don't think this is true, but I'm not totally clear on what you're arguing.
Hey I got pulled away from this conversation and didn't continue.

In most systems where the server never sees your password, they store a hash that is generated from the password.

Then the login code on the client takes the password, performs the same operation and then sends either that same hash to the server, or one that's simple to calculate from it.

So if I steal your password file, I can log in as everybody without even knowing what their passwords are. I just change the code in the client to skip the hash generation part of the authentication algorithm and use the one I supply.

The idea with asymmetric ciphers (at least the ones that interest us) is that one party HAS to know the secret, and the other has no way to get it.

I'm even more confused now.

I think you're saying that this system is better because, since it uses public key pairs, an attacker who steals the password file doesn't know enough to log in as a different user.

Leaving aside that an attacker who steals your password file has probably mooted login security altogether, the attacker in this system seems to have exactly the same leverage as an attacker who steals a password file full of scrypt hashes.

Yes, there's a challenge/response scheme (like in SRP), so the communication part is slightly improved, but what I'm talking about is that the server stores public key, and this public key is deterministically derived from password, thus stealing the database of public keys from the server is equal to stealing the database of password hashes (like in SRP).
I haven't read their code or critiques of it, so I can't say if that's the case for this algorithm.

But for this class of algorithms, that doesn't have to be the case. Starting with a cryptographic hash could keep the key from being reversed to the input. There are probably other things that could help as well, like maybe not using the password in the public key at all.

It's not a question of reversing the hash, it's a question of what is the 'password validator' and what are the inputs to the algorithm which get you from 'candidate password' to 'compare result to the password validator and return true or false'.
How exactly does "starting with a cryptographic hash" solve this problem?

Remember, the attack is: start with "aardvark", run the deterministic key-generation process, hash, scrypt, elliptic curve and all, and check to see if you get the same result. If you don't, move on to "apple", then "ataxia" and so on.

The attacker has every piece of information in the system except the password string, which they can substitute with a dictionary.

I haven't had a chance to look at the code yet, but riddle me this: Are they eschewing salts entirely?
Yes. The same [password,name,host] tuple should produce the same keypair.
It looks like the client generates:

    S <- scrypt(zeroes, 
           SHA2(name, pw, host))

    secureSrand(s)

    keypair <- keygen(ecdh, secureRandom)
The client sends the pubkey to the server, the sever sends nonce challenges to the client.
I don't understand the second line of your pseudocode -- I read the description as not having any ("external") random bytes, just the PRNG initialized from the seed derived from scrypt:

"CBcrypt combines publicly known authentication factors (typically username and server id) with secret factors (password), applies a rate-limiting work function such as scrypt or pbkdf2, to deterministically generate a random seed. This seed is then used in a pseudo-random number generator (prng), and the prng is used as the basis for generating a public/private keypair."

EDIT: ah, got it (libc! :), secureSrand means "initialize PRNG with seed", so we're talking about the same thing.

Yes, "srand" was my shorthand for that, but since I just invented that shorthand, I'm not surprised it was confusing.

Also: is it safe to use a secret-seeded DRBG as a CSPRNG for ECDH keygen? The time it will take to generate the ECDH key will be secret-dependent, right?

(I'm sure it doesn't matter in this case. Just curious about the general case.)

I think it's safe, but we need real cryptographers to figure this out (does Matthew Green approving miniLock count?). With proper Curve25519 implementations key generation timing shouldn't be secret-depended: it's the same scalar multiplication (crypto_scalarmult_base).
The benefit here is you don't have to trust the server to actually store an scrypt hash properly.

And it's been pretty obvious that most service providers have no idea what they're doing and can't be trusted to do that.

Yes, you do have to trust the server.
Specifically, to deliver the Javascript in the first place.
No, I mean, you have to trust it to store password hashes, just like in any other scheme. The ECDH public key is generated deterministically from the password. If you have it, you can crack it to recover the password.
His underlying assumption is that given an ECDH public-key it is computationally infeasible to derive the private key / seed that went into creating it (via brute force). I suppose that's a fair assumption if your password has high enough entropy or is stretched sufficiently?
No. The security of the password storage in this system has nothing to do with that of ECDH.
This sounds worse than I imagined when I was reading through it earlier. Sorry if I muddied the waters earlier.
There's an issue with passwords/keys not sent to the server: what if the user forgets the password?

No "Forgot your password?" functionality available (reset token), since the server does not store password (hashed or otherwise).

You can email the user a one-time token for setting a new password.

You should never store the users password.

When you email a token, you're back to square 1 and will need 2 factor auth.

In addition the reset password is not possible when the data is encrypted on the client side. This is how TrueCrypt works - if you forget the password, all your data is lost.

Data isn't encrypted on the client side only the "password" is.
Data encryption on the client side is one of the 5 features. See https://github.com/rahvee/CBcrypt and the "Tech Details Video".

"Users are able to login to servers, and encrypt all their data, without ever exposing their password or encryption keys to the server."

"And if the user's data on the compromised server is encrypted using the user's keypair, then even the users' data is still protected."

(comment deleted)
So essentially this is a really convoluted way of concatenating username, password, and domain then running scrypt() on it, and sending that to the server as the password instead of the raw password itself?

I actually read the Github page for this, and glanced over the C#. There's no realistic example of how this would work in practice, and I have unanswered questions. This would legitimately solve some phishing scenarios and MIGHT slightly mitigate password reuse scenarios (since they know username + domain, they now need to spend time cracking scrypt() on the password). The arguments that it helps user privacy (NSA something something) are tin foil hat wearing jibberish.

Overall: Meh. If they're serious about this, they need more than a vague proposal.

PS - And a password manager solves all of the named issues with less complexity in my opinion.

There is a (somewhat) practical version of this implemented as a bookmarklet: http://www.supergenpass.com/

I used it for years (for unimportant things) before switching to a password manager. It's technically not secure against a malicious site that sniffs for the existence of the bookmarklet window, but it's a good way to get slightly better security on sites you'd other reuse the same password for.

I use a much simpler version of the idea in the form of PwdHash: https://www.pwdhash.com/

Before submitting passwords to a website, they're replaced with a hashed version which incorporates the domain, so passwords are unique to each domain. (The hash isn't anything fancy, so it could definitely be modernized with scrypt or bcrypt or whatever is fashionable.)

I've used it for years and it always works well, apart from the sites that claim my password is too long. It requires no support from the website, just a simple browser extension.

Why not just use a password manager?
(comment deleted)
What happens if your password is leaked? It seems to generate the same hash every time, so you would have to change the site password. And if you have to start remembering "Well my password for every site is 'pumpkin' EXCEPT for Wordpress, where my site password is 'bagel'," that list is only going to grow with time as websites inevitably get hacked. So once you've got five or so site-specific passwords, how is it any better than the password memory problem this was originally trying to solve?
I thought about using pwgen locally with a combination of domain, username and password as a hashed seed. But like you mentioned, trying to remember how often i had to change the password (or had restrictions applied only at a particular site, which are pretty ridicules sometimes) makes this not really a worthwhile solution. Albeit this, its not completely useless. If you have specific rules how to create new passwords (a counter for example) and to circumvent specific restrictions, one could iterate through the possibilities rather quickly. One thing that's unbeatable about this solution is that no password store is needed and so none could be lost, which drove my initial thought to this.
I used to use that too before I adopted a password manager.

Pwdhash uses md5, which is relatively fast. According to the below, even a strong master password could be derived in less than about 30 days.

https://security.stackexchange.com/questions/52355/how-secur...

On the other hand, the odds you'll be the victim of such a targeted attack are presumably pretty low. This at least gets you out of the category of "low-hanging fruit" for an attacker.

I don't hate the idea, but I could never use this while so many sites still have dumb validation rules. It would drive me crazy if I had to remember what sites this didn't work with.
Their generation isn't great. They should tweak the resulting password to ensure that it passes most common tests. I think I would enforce

   - 10 characters
   - at least one punctuation
   - at least one digit
   - at least one upper case
   - at least one lower case
By coercing the password to have this form you're losing a trivial amount of entropy, but you'll pass the vast majority of password policies.

Also add a nonce to the password generation (1, 2, 3, 4) so that you can change it if needed or required. No need to remember the nonce, just try a few until you can login.

I don't remember where off the top of my head, but I'm pretty sure I've seen sites that had a "no punctuation in passwords" rule. I think at least one of them was a bank.
Makes sense, it's so their IT department can read it to you more easily over the phone.
Nespresso is one that immediately comes to mind as it's the most recent I've encountered besides my bank. I went to order some pods for my mum as a gift only to discover that their password restrictions were not only draconian but stupid. The moment a site prohibits punctuation (especially single quotes as they did) is the moment I suspect they're storing passwords in plain text.

It's not directly related, but I'm reminded of this Hall of Shame I stumbled upon from some HN comment a few weeks ago: http://plaintextoffenders.com/

PwdHash only puts punctuation in generated passwords if the password you provide has it, so it tries to be smart.
Also, some sites have things like capital letter cannot be the first character. Punctuation can't follow a digit. At most 8 characters... The list goes on.
See my other comment in this subthread about my own version of the deterministic password generator concept. It allows passwords to have site-specific rules for how they're generated and also allows rotating individual site passwords.
PwdHash has serious usability issues: http://people.scs.carleton.ca/~paulv/papers/usenix06.pdf

In particular, the fact that you type your password into the password field means that failing to invoke PwdHash means you either register with your raw password (making it worse than useless) or just leak your raw password with failed login attempts.

The password manager model (e.g. LastPass) is clearly superior in my opinion because the user doesn't know their passwords. Largely the only way to input your password is the correct way. Also determining the password for one site provides no information for others (assuming you're random generating the passwords). For PwdHash, if you crack the password you have a lot of information for breaking all the user's other accounts (because presumably they're reusing the same base password).

I've been actually using a similar solution for my own passwords, having built a small utility myself: https://github.com/alexandru/parolamea ; it works by doing an HMAC+SHA256 between an easily rememberable service identifier (like the domain) and the secret master password and then I'm converting that to base 64.

Using SHA is of course discouraged, because compared to bcrypt the collision attack can be parallelized on top of GPUs and you can try tens of billions of combinations or more on top of commodity hardware. But here's the gist - with a good salt, the complexity of finding collisions is about 2^256. Basically without knowing the salt, you're shit out of luck, because all the PC or GPU power in the world cannot crack 2^256. You can't use rainbow tables either and there are no shortcuts discovered for SHA-256, like you've got for MD5. And then you've got things like bcrypt, an 11 years old algorithms that can't be parallelized over GPUs and that's still unbreakable.

I disagree with you. This doesn't just slightly mitigate password reuse. It actually solves it.

And for me it's way better than a password manager because (a) it isn't a single point of failure like LastPass, (b) you don't have to trust a proprietary binary blob like 1Password, (c) you don't run into the risk of losing access, as everything is in your head, (d) when one of your passwords is compromised, you have the incentive to change the master passwords which will trigger a change of all the passwords, everywhere and (e) best of all it's free.

I've been using something similar of my own making, and I've been meaning to clean it up and publish it at some point. Since I have enough side projects going that I have no idea when that will be, I'll share a couple features of mine that I think make it unique and which I think should be incorporated into the others.

The general concept I stole from somewhere else -- you've got a stored list of sites and when you type your master password in a field, each site in the list then gets a "copy password" button based on the site name + master password. But this isn't quite flexible enough for general use, so I added some features:

First, each site has a 'version' field which becomes just another piece of data input to the hash. This makes it so you can rotate passwords on a particular site without changing your master password: increment this number and you get a whole new password.

Second, each site has a password 'scheme' which allows for disparate password requirements on different sites. The underlying generation algorithm is the same, but rather than converting the hash output to a base64 number and using it directly, the hash output is used to deterministically select characters based on the rule set. Roughly, each scheme has an arbitrary number of character "classes" that may be included (e.g. "numbers", "letters", and "symbols") and each scheme may specify a minimum number of characters from each class (a typical rule being that that min=1 for numbers and symbols). So the class-specific minimums are satisfied, then the rest of the characters are selected from all classes equally, then a few more bytes of hash are consumed to deterministically change the order of the selected chars (otherwise you'd always end up with your minimum two special characters at the front, for example, which technically weakens the password). Each site also can have a distinct password length setting. Currently I only have three or four different "schemes" defined and haven't had the need to add one in a while so they're all hardcoded, but one could easily imagine having a "password scheme editor" which lets you define new ones with a few primitive rule types.

And third, each site has a "last changed" date which helps me keep on top of which site passwords haven't been rotated in a while. If you change your master password every time you need to roll one site's password, this probably isn't an issue for you, but I definitely prefer to avoid the ritual of changing passwords on every site I use at once.

My impetus for all the password scheme complexity is that I found that more straightforward password generators simply don't work on all sites, and I hated having exceptions. The site where I pay my electric bill, for example, doesn't allow exclamation points in passwords, and they must be between 6 and 8 characters. Lame to be sure, but I really have no choice but to go along, so my password generator must too.

All that said about my password generator, I think this is a fundamentally different approach to the problem and I think the cbcrypt approach is ultimately more interesting if we can get it incorporated into browsers. I've long thought we should expose some sort of modified SSH-agent functionality to the browser JS API so sites could do public key auth for login (with the appropriate user prompting, of course -- just allowing websites unfettered access to your SSH agent would obviously be a terrible idea).

I don't think that's right. There's a keypair and although the text of the article doesn't say it, I see evidence of a Challenge-Response in the source code (they have files named Challenge and ChallengeResponse).
Password manager still have weaknesses. For one, you are still sending the private key to the server. This may happen in plaintext, or the password may not be encrypted/protected properly server-side. And it requires you to keep a database of passwords that you need to synchronize between all of your devices.

Using something like public key authentication allows you to use the same public key for every website. Your password management software and synchronization strategies are both suddenly a lot simpler. Server-side mistakes are less problematic to the end user.

It removes several points of failure, and has greater flexibility against user, server, and developer mistakes.

There are client side password managers. Example: keepass/keepassx.
My reaction is one of those "I'm not sure if I should feel stupid or not" moments, but: rightly-built applications already don't expose passwords to employees in that they aren't (or at least, shouldn't be) generally persisted. Usually the plaintext passwords live in volatile memory briefly while the server computes a hash of some kind for comparing with what is stored. I suppose an admin could run a web application under some sort of memory profiler, or take a dump at exactly the right moment, and capture a plaintext password, but that seems pretty far-fetched.

CBCrypt seems to me to introduce a lot more complexity into the entire application space with very little real gain. I'm certainly open to being convinced (especially because I'm waffling on whether or not this is a dumb reaction).

The idea is that you're implicitly trusting the company (or website), as well as anyone who has (whether legit or not) access, to only keep that password in memory, and it's preferable to authenticate without requiring that trust.
I can agree to this: this allows a user to not have to trust that the company running the application set up password authentication properly.

But still: I just can't get worked up about this at all. I'd rather see pgp get implemented in browsers before this.

You can already use TLS client certificates - the UI is just terrible is all.
People generally aren't carefully clearing passwords from memory after use, and ideally GC runs aren't happening all that often. "Exactly the right moment" could easily extend out to many minutes.
Right. So there's an I suppose in there somewhere, and my response is still pretty much: "meh". The people who might could possibly get access to that password already have access to all the data being protected by that password, and if they were so hell-bent on using your password to break into other sites, they could do that anyway by brute forcing what CBCrypt produces.
Brute forcing a password hash is a lot different from being able to trivially extract it from memory long after it's been used.
The momentary exposure in memory was the downfall of Lavabit. It is actually trivial to capture passwords submitted to servers during the momentary exposure. For example, when you login to a Drupal or Wordpress site over HTTPS, the POST gets submitted to a particular form - which is just a PHP file on the server, trivially editable. The password exists as one of the submitted form variables, which PHP then passes to bcrypt (or whatever).
Whatever happened to challenge-response schemes in the vein of CRAM-MD5?
Good question. This would be even better.
Yeah, there are plenty of authentication systems out there for this kind of thing, and preferably something like SRP would be used.
And before SRP there was EKE. I thought the main reason it never saw wider use was because it was patented. Although according to Wikipedia, those patents expired in 2011 and 2013.
Challenge response schemes generally require the server to have the password in a recoverable format so that both sides can generate identical hashes. IMO the current state of things is better than it would be with 1000s of random websites with DBs full of clear-text passwords.
> Challenge response schemes generally require the server to have the password in a recoverable format so that both sides can generate identical hashes.

Do they? Doesn't the server just need to share the salt and algorithm parameters it stores anyway?

The server can store the salt and parameters, although it gets really hairy if you decide that MD5 is too weak and now you want to upgrade to SHA-1 or SHA-256.
Nah. Hashes of hashes works just fine, and allows the actual password value to never be stored plaintext. A simple example:

Stored on server: x = SHA256("mypassword")

Server challenge to client: send a secure random nonce

Client sends: c = HMACSHA256(nonce, SHA256("mypassword"))

Server verifies: c == HMACSHA256(nonce, x)

In some implementations, the server challenge and 'c' are encrypted using 'x' or some derivation that both sides can create. In addition, salts can remove the sensitivity of the stored 'x' values (https://en.wikipedia.org/wiki/Salted_Challenge_Response_Auth...)

The problem with hashes of hashes is now instead of the password being directly grabbed, the hash is directly grabbed, which can be thrown through the challenge-response system with no problem.

This only mitigates knowing the password itself, not anything to do with authentication.

> The problem with hashes of hashes is now instead of the password being directly grabbed, the hash is directly grabbed, which can be thrown through the challenge-response system with no problem.

But now you have to grab the hash first from one of the endpoints, MITMing the connection no longer suffices to impersonate the user.

I suppose public key schemes would be preferable, but deploying those isn't feasible for a lot of use cases.

The state of the art for SASL is SCRAM-SHA-1. It uses challenge/response authentication and it allows the server and the client to only store salted hashes (using PBKDF2 with a configurable number of rounds). It also uses mutual authentication (the server also proves to the client that it has the hashed password, not just the other way around).

No idea how that compares to TFA, because they have no documentation.

Why can't we use PGP tu login to websites?

That way the server only has your public key (and everyone can have it anyway).

From a usability perspective, it's probably because dealing with keys that can't just be memorized is hard for most people.
Seems like the solution already exist : password managers.

But yes, having small memorizable passwords is much more convenient.

Can you imagine how easy it would be with browser integration, though? :-)

"The site is asking you to sign up. What secure login key would you like to use?

* Personal

* Office

* Contracting"

This is what I am planning for a project of mine called AutoAuth. It's put on hold cause I have no idea how to write Chrome extensions.
This is what I am planning for a project of mine called AutoAuth. It's put on hold cause I have no idea how to write Chrome extensions.
Why even have those if you are, presumably, presenting yourself as the same person in each case?

You are person 'A' and you have the private key (and maybe password used to unlock the key) to prove this fact.

You don't need different private keys for each and the remote end just has a public key that says the account belongs to person 'A' and that key is public.

I guess you're right. :-)

The only usage case would be if someone wanted multiple accounts at the same site, and that would be rare indeed.

The only other real concern, site hacks/collaboration leaking where you're a member of by public key, wouldn't be alleviated by merely a handful of keys anyways: you'd need unique keypairs for each to be truly secure.

Mozilla Persona / BrowserID might be of interest to you.
You can use client certificate for authentication using TLS. The main difficulty is how dire the UI experience is on the browser side - it's evidently little more than an afterthought for vendors.
I think its a chicken and egg problem: very few services use it, so no browser vendor cares to improve the UX; and the UX sucks, so very few services choose to use it.

It probably won't ever change unless one of the browser vendors that is also an vendor of popular online services decides that it would be good to enable it in its own services, and picks up the cost of upgrading its own UX to support that (creating pressure on other browser vendors, while also lowering the barrier for other online services.)

The problem is that all of the browser vendors that could do it are pushing their own, online authentications schemes, and have no interest in client-based authentication.

The server has all the inputs except the password and enough information to validate if it has guessed the right password. So password guessing/dictionary attacks are still viable, especially with state level adversary. BUT users are given a false sense of security because "the password is never sent to the server". So we can expect users to (on average) use worse passwords and reuse passwords inappropriately.

IMO, if you are going to use client certificates you should be just be using standard client certificates with whatever your OS provides to generate them.

I'd rather just use SAML, OAuth, SQRL, etc.
I don't see how this can claim to prevent phishing attacks. A fake site can still just steal your username and password as usual, and then go to the real site and log in with them.

Am I missing something?

Obviously there is still a benefit to not sending your password to the real site, but their anti-phishing claims seem… phishy.

This is only a tiny improvement. Any password cracker can figure out your password just from the hash anyway. What we really need is industry support for and general acceptance of two-factor passwords. I want to generate one-time passwords from my smartwatch, have them sent to my keyboard or computer directly, and be able to log in to gmail and through ssh alike.

Is it just me, or does the current way we handle passwords feel archaic, even while we still use them?

The main problem this project is trying to mitigate is the password reuse. If user A uses the same password for a lot of sites, a malicious person B is able to convince A to join a new service, like a cat photo sharing app or something like that. If A uses his/her same usual password, B automatically gets access to all A's accounts.

The way this project tries to solve the problem is by hashing the password from the client side so that sites never get the real password, but a hash instead. As other commenters have pointed out, this is not entirely effective because the attacker still can crack the hash. It just makes the problem more difficult depending on the size of the original password.

The real solution to this problem is to stop sharing password at all. Use a password manager for that purpose.

A good hash like scrypt makes the password very, very hard to crack unless it's a very poor password.

The real problem with this is that it'd never be feasible to convert enough sites and apps to using it to make it safe to reuse passwords

As the page points at, the malicious website does not recieve a hash of the password, but rather a public key derivied from the password: "The worst attack a malicious server can mount is an expensive brute force attack, attempting to overpower the rate-limiting function and eventually guess a password that recreates the exposed public key." That is a very different attack to try to pull off.
Phising sites can bypass this by creating an input field which looks like a password input field but isn't actually one.

+1 for password managers or U2F style authentication systems.

How is this any different than every other "hash a bunch of shit and throw in a salt" half-baked encryption idea people continually invent?
I'm working on the same problem, and there's a working prototype https://github.com/sakurity/truefactor

The problem is bigger than that - we should stop making users type password at all. There should be an authentication module any website could use to store and retrieve credentials from. Check out Truefactor.

> There should be an authentication module any website could use to store and retrieve credentials from.

How do you plan to do that securely?

Open truefactor:// app. Currently there is only a Web version and it has serious downsides (web crypto is a bad idea), but think of it as a Light version. Desktop apps to come later.
I was looking for more of a write up. I'm just wondering how/where the credentials get cached and how you securely know the user re-connecting is the user who previously disconnected.
Credentials are encrypted with passphrase and seamlessly stored on the server by token=sha256(passphrase). https://truefactor.io/
Site gives me a login page. I make a login and I get no information about the service just user options.

Also where is the salt stored? SHA256 is pretty easy to brute force even salted.

Email itself is salt (or rather public part of passphrase). So from email+passphrase encryptionKey is derived using scrypt. So it's actually sha(scrypt(email+passphrase))
> The problem is bigger than that - we should stop making users type password at all. There should be an authentication module any website could use to store and retrieve credentials from.

We have the solution already in HTTPS client certificates. Browsers all have mechanisms for generating and storing them. The only problem is that no one uses them.

Is there JS API to use HTTPS certs to sign specific strings? Like "send 1 bitcoin to X"
Why would you make all of your commit messages "1", instead of explaining what the added code does in each?
I'm a single developer, imo no one will read these messages until Beta version.
Or better still, just create a RESTful stateless API and implement JWT?
so the hash of the password becomes the password. i don't see the gains tbh
(comment deleted)