Let’s talk about PAKE
blog.cryptographyengineering.com
blog.cryptographyengineering.com
PAKEs are great for low-entropy secrets, but they don't have to be static: you can generate them on the fly too. Every time you have a human-mediated channel that eventually needs to agree on a strong secret, PAKEs are good. So, if you have a device that you want to pair with an existing device with an untrusted third party PAKEs are super great. You can use this to safely send a file across the ether by just sharing a short string like "2-bonobo-magic; see magic-wormhole.
I therefore disagree with the notion that a PAKE being symmetric is a downside: I just think that they're different tools for different tasks, and we should talk about sPAKEs and aPAKEs specifically. Symmetric PAKEs are worse for password auth: I just think PAKEs are not a high priority for password auth. There are two problems with passwords: cred stuffing and phishing (fundamentally the same attack: an attacker gets a password "out of band" and then replays it) and PAKEs solve neither.
[magic-wormhole]: https://github.com/warner/magic-wormhole
Their threat model is "server is compromised by an attacker, who then vacuums up all the cleartext passwords". Assuming that under normal operations there's some fancy UI that takes the password and handles the PAKE stuff (which it will have to be, until browsers support it), there's nothing stopping that attacker from simply adding malicious code that fire off your cleartext password.
If you want user authentication security, use client side TLS certs. 1) the UI is built into all major browsers, and can't be faked, and 2) the server doesn't require the CA's private key, only the server generating new certs needs it. In the above threat model, the worst that can happen if an attacker compromises the server is he can MITM the traffic at the time... but the attacker will never capture user credentials that can be used in the future, or be used to decrypt past communications.
Client certs suffer from questions like "as a user, how do I handle multiple devices? Logging in from my phone? Logging in from the biz center at some hotel / my friend's phone / etc?
The UX for client certs in browsers makes it a pain to use even as a tech-savvy person; if we want it to actually become popular as a web auth method, it has to start with better UX.
As for logging in on untrusted devices (biz center, friend's PC, etc)... you shouldn't be doing that under any circumstances in a high security situation.
You also end up delegating the authentication to your transport layer which is never that good of an idea.
You can require a password, but that's true for text files on a Linux system too. So why don't most people use a secret password to protect a file with a secret key inside it? Because it's yet more pointless busy work, again a stock in trade of Microsoft environments.
Also, because this is so very annoying you don't need physical access but only console access, which you can of course get remotely, as otherwise administrators of the mountains of Windows servers set up this way couldn't type in all the passwords needed over RDP every day. (If you're lucky they are using an encrypted RDP session to do this...)
All modern laptops ship with TPM that basically allows provisioning private keys in an non exportable way. Additionally server can remotely attest that the key is stored in the TPM. (your HSM remark probably covers this though)
CryptoAPI does not hand over the key and delegate signing and encryption to the application. Instead, it provides APIs for signing and encryption and does not disclose the private key.
There is no proxy, they keys live in your process. Because Windows is proprietary they can do the moral equivalent of:
if (key->flags & CRYPT_EXPORTABLE) {
export(key)
} else {
error_not_exportable
}
If you did this in OpenSSH, everybody would laugh because they could see it in the source code. "This doesn't make the key unexportable Beavis, you idiot". But in Windows they can solemnly announce that the key isn't exportable and as you've demonstrated, people believe them even though some introspection tells us this can't be true (Where is the key? Like, really, where - it isn't in a proxy because there isn't one... when we load it _our_ process gets bigger and in a debugger we can see it's in our memory, just CryptoAPI tells us we're not supposed to export it...)I see this as a perfect case for "logging into your browser" (Chrome Sync/Firefox Sync/iCloud Safari Keychain sync/etc.) Why not have any issued client certs be global to your "browser account" rather than local to your device? The cert bundles can also be transferred and stored using end-to-end encryption (like iMessage keybags.)
Sure, now you can't tell which of a person's devices they're on from just the cert you're seeing. That's what cookies or localStorage would be for, since they explicitly don't sync between devices. Client cert for AAA + session cookie for holding the server-side connection ID.
Lack of native browser support seems to be what held up SRP. Hopefully OPAQUE can make it farther.
Remember, virtually all mainstream applications accept logins over TLS (exclusively) at this point, so being able to authenticate and encrypt a channel with a passphrase isn't all that valuable. As a security engineer working for a startup, there aren't a lot of new features I'd be able to build after having adopted SRP, and essentially none of my real current challenges (credential stuffing, phishing) would get any easier.
That's not to say OPAQUE isn't useful; it's just not that useful in SAAS-type application settings.
The "real" issue PAKEs address is long-term compromise, where an attacker can observe passwords out of memory. For that matter: for attackers to get log files in the first place, 9 times out of 10 they had to get RCE somewhere in prod, and that is already game over. And, there's a lot of things you'd do first do address game-over than replacing your TLS login POST with a PAKE handshake.
PAKEs don't address Heartbleed-like issues; in fact, they create more opportunities for them.
When modern browsers trust 150 Certificate Authorities [0] (and the untold subordinate/wildcard certs that were further issued by them), it's reassuring to know that I've verified that the server actually had my password (or a derivative), which makes it even harder to phish or impersonate a server with a stolen/malicious signed TLS key (this is all assuming the browser has a special non-spoofable dialog when authenticating via a PAKE).
For example, picture all of the people who have lost their banking passwords to phishing sites. If PAKEs were used, then the attacker gets nothing except a single guess at the password. If the attacker already knew the user's password, then the user already lost.
I agree the PAKE theoretically does a better job on this problem. But does it do that job so much better as to justify its inclusion in a protocol?
On the other hand, a PAKE failure due to the server not having its half of the authentication data is not possible to ignore, so people will be forced to get it right.
The certificate used for the HTTP transaction where your credentials are submitted may be completely different from the one used to present the web form you filled them into.
A sneaky bad guy can let you talk to the real Bob for every single HTTP transaction aside from the one they want to capture, and intercede just for that single case, then drop back out silently, leaving you talking to Bob directly as before.
The web browser's own checks (including matching the FQDN against the certificate) run every single time - if they spot Eve taking Bob's place they'll freak out, but any human checks like "Look at the certificate in Certainly Something" (the nice certificate view for Firefox) only happen when a human gets to intervene which may not happen at all at key moments.
Imagine you go to https://www.example.com/ to log in
It presents a form with a submission target of login.example.com, your browser does a POST to https://login.example.com/login.form/ and it gets back a 30x redirect to https://www.example.com/welcome/
When did you get to examine that certificate for login.example.com? The answer in every browser I've seen is not at all, because it responded with a 30x so the page never finished and displayed.
That's not what the link you provided shows.
It lists 150 CA roots. 20 of those roots lack a "websites" trust bit, which means the web browser does not trust those roots (Mozilla also has an email client even if it's not much loved)
Furthermore, the 130 of those roots that are trusted in a web browser are operated by only 52 distinct Certificate Authorities. CAs operate several roots either because of business consolidation or segmentation, for example DigiCert operates 23 of the web trusted CAs you linked because they purchased Symantec's business in 2017 and are in the process of replacing Symantec's soon-to-be-untrusted hierarchy.
It's very strange to merge subordinates and wildcards which aren't the same kind of thing at all. Unconstrained subordinates are, in fact, tallied by Mozilla and they're on the adjacent page:
https://wiki.mozilla.org/CA/Intermediate_Certificates
The vast majority of these intermediates are just for issuance and remain entirely under both physical control and legal authority of the CA, so they make no difference to the trust picture they just reduce the exposure if things go wrong.
Why not implement a client-side PAKE API in the browser? It could be designed to disallow any server-sent code from accessing client credentials in plaintext, while still allowing styling and layout of credentials fields (this might be impossible, though). Or alternatively, let the browser handle the login/credentials UI, and build in a seamless password manager integration.
I can't seem to find any relevant links/bugs now though - maybe the decision was reversed? Or I'm simply wrong?
Wikipedia is actually more clear in this case:
> an eavesdropper or man in the middle cannot obtain enough information to be able to brute force guess a password without further interactions with the parties for each (few) guesses. This means that strong security can be obtained using weak passwords.
Looking into SRP, it seems that a server can still brute force a stored login. While cool, TLS achieves the same goal in popular login systems: eavesdroppers cannot learn anything (in fact, they cannot even make a single attempt at the password, unlike with PAKE). The other advantage of PAKE, the server never receiving the password, can be done with client side hashing (for which I've been advocating for years, as it would have prevented many issues).
At some point I tried talking to people to make client side hashing an option in <input type=password hashmethod=X>, but nobody cared more than saying "yeah sounds good" when prompted. If this would have been implemented and would have become mainstream, browsers can warn if a site (suddenly) doesn't use it, much like warning for http (or even pinning a la hsts). So as it is, it indeed cannot be done securely in browsers.
(Note: I am not saying this is a good idea! It's OPAQUE but worse.)
(I don't think this is a good idea, I'm just saying technically your criticism doesn't apply, though you are correct in how SRI works. I'm so sorry :()
Whereas a proper asymmetric PAKE means that even if your password file is breached, the attacker can’t use the leaked hashes to log into the service without first cracking each password.
The problem you point out: that password hashes can be brute-force cracked, is unfortunately not a problem we can solve. Consider that a server can always “attempt a login to itself”, so given a password database you can always run a dictionary attack. The only thing truly protecting you in that case is the combination of strong passwords and a hard password hashing algorithm. Passwords are fundamentally a drag.
Using a hardware one-way function you can ensure that even if your database is breached or disclosed, attackers cannot brute-force outside of your environment (e.g. the hashed are “anchored” to your systems).
You can construct such a function using something like CloudHSM (pity that KMS cannot be coaxed to be deterministic or you could use that). All you need is an encrypt operation with no corresponding decrypt or way to extract the key.
I’m surprised that more large online services don’t use anchoring.
It's more important that bad implementations are removed immediately. Personally I'd rather get rid of all of my passwords and use FIDO2 or perhaps even something through touch-id on my iOS/Mac. At this point every password I have is unique thanks to great password managers.
FIDO2 should be implemented in many more areas but it shouldn't be exclusively relied on for authentication. Authentication should require proof of person/entity (something you have, a FIDO2 key) and proof of volition (using a password stored in their brain that their will decides to produce/disclose)
Or someone else's will decides to shoulder-surf / keylog the password :)
There are many specific auth "factors":
- valid signature from an extrernal hardware token (U2F/WebAuthn via e.g. YubiKey)
- valid signature from a device's embedded token/TPM (something like Touch ID / Windows Hello / Android keystore thing)
- … as a WebAuthn implementation
- … in response to a push notification on another device (Twitter, if they still have that)
- … in response to a QR code (SQRL, Yandex.Key)
- one-time code via push notification to another device (Apple)- one-time code generated from a shared secret key (TOTP)
- one-time sign-in link via email (Tumblr)
- passwords
- secret questions (like extra passwords but worse)
- behavior pattern analysis (IIRC Google showed an Android demo that looked at keyboard typing patterns and whatnot)
A good auth system should combine multiple factors in a correct way to minimize both impersonation and lockout chances, and maximize usability. How? That's the challenge…
Kerberos has a draft for adding SPAKE to Kerberos: https://tools.ietf.org/html/draft-ietf-kitten-krb-spake-prea...
This was implemented sometime around March in MIT Kerberos: https://github.com/krb5/krb5/pull/741
One of the interesting use cases would be to add 2FA support to the Kerberos protocol, but that support is still pending last I checked.
A second draft that is useful for SPAKE would be improved Channel Binding (CBs) support: https://tools.ietf.org/html/draft-ietf-kitten-channel-bound-...
CBs are still WIP upstream: https://github.com/krb5/krb5/pull/685
Channel bindings allow Kerberos to piggy back on top of an existing encrypted channel (e.g., TLS). When doing 2FA with SPAKE in a browser, this means that we can take advantage of the security guarantees of the TLS protocol by ensuring the value of the final handshake is the same. This is most helpful for SSO-type scenarios.
If anyone wants to comment on either RFC, I'm sure the Kitten WG would be happy to take feedback: https://tools.ietf.org/wg/kitten/
Disclosure: I work closely with several of these folks and worked on the CBs PR.
As it stands, the PAKE is better than what they had, but not ridiculously better in the way U2F is over TOTP for example.
To the degree that it's the browsers' limitations, couldn't the browser makers make a standard authentication client (or at least an API) with whatever tech and features are needed? A sandboxed mini-application, hardened, that passes a 'yes', 'no', or 'timeout' to the browser? Not every website would utilize it, but certainly the well-resourced ones could at first (FAANG, banks, etc.) and web server engines, frameworks, content management systems, etc. could incorporate the server side over time. It doesn't seem expensive, and the ROI would seem to enormous - safe authentication over the Internet. But maybe I'm solving the wrong problem?
For the Gophers out there, I wrote a Go library for doing PAKE [1], which I use for a data transfer utility [2].
[0]: https://crypto.stanford.edu/~dabo/cryptobook/BonehShoup_0_4....
Its nice to hear that there are PAKEs that are not tied to specific password hashing functions.
Our current design is basically the same, but we generate and store a random salt server-side and present that to the client along with the challenge. Using a deterministic salt based on the username and domain is a nice idea - we actually do something similar if the client presents an incorrect username to avoid leaking whether the account exists (we send salt = HMAC(secret, username) in that case).
> The earliest key exchange protocols — like classical Diffie-Hellman — were unauthenticated, which made them vulnerable to man-in-the-middle attacks.
From Wikipedia (https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exc...):
> The Diffie–Hellman key exchange method allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure channel.
Maybe there's something I'm not understanding, but I thought the point of DH was you could exchange something even when other people are listening. You can see in the example in the article that it does't matter what Eve can see.
If somebody is passively observing/recording the traffic, they wont know what the negotiated shared secret was. However, if they actively insert themselves in the middle, they can negotiate a shared key with you, and another one with the final destination. Then they can decrypt messages from you with the shared secret they negotiated with you, re-encrypt with the shared secret they negotiated with the other party and forward them on.
Alice and Eve do DH exchange and agree upon a secret. Eve and Bob do a DH exchange and also agree upon a secret. Now Eve knows both these secrets and can relay messages between Alice and Bob. Both think they are talking securely to each other, but they are actually talking to Eve instead
Bob starts handshake with Alice:
Bob -> Alice
Eve intercepts and finishes handshake, claiming to be Alice:
Bob <-> Eve Alice
Eve starts and completes handshake with Alice, claiming to be Bob:
Bob <-> Eve <-> Alice
And now, Bob and Alice think they're sending messages to each other, but actually they're sending messages to Eve, which she can read and then forward-on so that they don't notice the difference.
Unless Bob and Alice can authenticate the person they exchange keys with, the whole exchange can be subverted.
This and similar attacks is why cryptographers strongly believe now that authentication is inseparable from encryption and that the encryption should basically never be offered independently (which wasn't properly understood back in the 80s and early 90s, hence crappy protocols like PGP-email where authentication is a optional plugin).
This part:
> Maybe there's something I'm not understanding, but I thought the point of DH was you could exchange something even when other people are listening
DH does protect you against people listening. It doesn't help if they can actively change what you hear. Passive eavesdroppers are thwarted, but an active MitM attack is not, which is where authenticating the other end comes in.
The common example of DH I've seen is that you can establish a secret key with someone in a crowded room, with everyone overhearing your conversation. In that example, our "authentication" is that we can visually see the other person and we recognize them (or at least, we want to communicate with that person).
It's maybe obstructive to walk though what happens in TLS 1.3
Alice sends somebody her random DH key share. She addressed it to Bob but has no guarantee it isn't intercepted.
Somebody sends Alice their key share back - so now Alice and whoever this is has a shared key. All further traffic is encrypted.
Whoever it is sends Bob's certificate. A cert is a public document so this proves nothing on its own, but...
Then is the important step, they use Bob's private key to prove that they saw this whole conversation so far by signing a transcript of the whole thing including the key shares.
Once she receives the signature Alice can conclude this is Bob.