2
$\begingroup$

To my knowledge it works like this:

  1. The server receives the username-password values over a secure & encrypted channel.
  2. The username-password values are decrypted in the server and are present as plaintext.
  3. With the username the according salt gets retrieved for the user.
  4. The salt is appended to the plaintext-password and is finally hashed.
  5. The hash is compared to the stored hash and depending if the hashes match or not the user gets logged in or receives some sort of a message that says that the username / password is wrong.

Hypothetical problem: If for example we have a vicious programmer "Mallory" that works as a programmer for the company he could write a piece of code inside the authentication process to receive the plaintext password:

private bool Authentication(string username, string password)
{
    // Some code ...

    log($"{username}, {password}"); // Logs the plaintext username & password for Mallory

    // Some more code ...
}

For this example we assume that the company fully trusts Mallory and that nobody else ever checks the source code.


My questions are:

  • Is it possible to change this authentication mechanism in a way so that the password is never present as plaintext?

  • Is it possible to prevent this without changing the effort for a user, like introducing two-factor-authentication or something similar?

$\endgroup$
  • $\begingroup$ Passwords should be hashed not encrypted. So your #2 is wrong $\endgroup$ – PhillyNJ Jan 25 at 17:49
  • 1
    $\begingroup$ #2 is still referring to the transmission from the user to the server, i.e. TLS $\endgroup$ – AleksanderRas Jan 25 at 18:11
  • $\begingroup$ For the first question, maybe a system with a zero-knowledge proof can work out, but there is a few things to get around right (salt management in user side for instance) $\endgroup$ – Faulst Jan 25 at 18:38
3
$\begingroup$

This can be done with a cryptographic protocol called Password-Authenticated Key Exchange (PAKE). It comes in a few flavors:

  • Plain PAKE is a good fit for peer-to-peer connections. Both participants know the password in the clear, and use it as input to the PAKE protocol. If they both agree on the password, then they establish a shared secret key, safe from eavesdroppers. If the passwords disagree, they fail to establish a key.

  • Asymmetric PAKE (aPAKE) is a good fit for client-server connections. The client knows the password in the clear and the server holds only a "hash" of the password. (In practice, it's not exactly a hash but something more involved. The point is that the server doesn't know the password in the clear.) The two participants will establish a shared secret key only if the connecting client uses the correct password.

A good, accessible introduction to the state of the art can be found in this talk by Hugo Krawczyk earlier this month at the Real World Crypto symposium. Among other things that you can do with PAKE, he explicitly talks about aPAKE as a replacement for password-over-TLS (the typical approach for authentication that you described).

$\endgroup$
0
$\begingroup$

Secure Remote Password (SRP6a) protocol solves this. It is used as a mechanism for TLS negotiations in RFC 5054 and was added into OpenSSL. RFC 2945 covers password authentication although modern implementations will use a stronger hash function.

You can perform the protocol efficiently in JavaScript in a browser to authenticate against a webserver. Here is demo code of a browser authenticating against a Java server running Spring Security which is a mainstream technology in some large financial services companies.

It is quite remarkable that the protocol has been around a long time but isn’t widely known. People assume TLS is good enough despite the fact that there are many scenarios that lead to a stolen password even with correctly configured TLS.

$\endgroup$
  • 1
    $\begingroup$ "You can perform the protocol efficiently in JavaScript in a browser". Yes. But how does the necessary JavaScript comes in the browser in a way making it trustable? I do not see that solved in common browsers. Until that is, I see no practical difference between SRP6a (or other PAKE) and the common practice of sending the password in a TLS tunnel and praying that the user is smart enough not to key it in when the green lock is on for the wrong reason. $\endgroup$ – fgrieu Jan 26 at 12:34
  • $\begingroup$ the linked web page for the JS explains to use SRP over TLS and gives some examples of why this is a good idea. $\endgroup$ – simbo1905 Jan 26 at 12:46
  • $\begingroup$ I do not get it. How does the user of say Firefox proceed to log-in? How does s/he recognize that it is safe to type the password? I find no word about this in the linked pages. $\endgroup$ – fgrieu Jan 26 at 13:15
  • $\begingroup$ the linked web page for the JS recommends to use SRP over TLS as TLS gives a green lock and SRP stops the password moving to the memory and network space of the server. It gives some examples of what can go wrong there to leak the password once it had been transmitted safely over TLS. $\endgroup$ – simbo1905 Jan 26 at 13:28
  • $\begingroup$ I was involved in the commissioning of an online banking system where during operational acceptance testing some whitehat pen testing was performed. TSL was working fine but a misconfiguration between the webservers terminating TLS and the application servers rendering the customers data caused random memory blocks to be returned to the attacker throwing noise at the server over TLS so leaked passwords. Heartbleed was a bug in OpenSSL with same sort of symptom that a remote attacker accessed raw memory over TLS. any combination of defences can fail so simply don’t transmit it to the server. $\endgroup$ – simbo1905 Jan 26 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.