5

When using 2-factor-authentication using plain TOTP, the secret is stored on both the client and the server. This in turn means, that anyone with access to the database (and a key for it) knows the 2fa-secret of all the users. Why is this acceptable? Storing plaintext passwords has been deemed unacceptable a long time ago.

Public key cryptography is a perfect solution for this; one could combine it with TOTP. The client generates a private/public-key pair and the TOTP-secret and sends the public key and the secret to the server. The client then generates a TOTP-token, encrypts it with the private key and sends it to the server which can then verify it. Note that this encryption could also be implemented inside an app like "Google Authenticator" in a way that the user would just have to type it out as well.

This solution seems a lot better to me as nobody on the server-side can know the private key. Why is it, or any other such alternative, not used in practice?

schroeder
  • 123,438
  • 55
  • 284
  • 319
Gamer2015
  • 707
  • 4
  • 12
  • If I am not getting you wrong, the secret is sent to the server in plain, right? And the only thing stopping others from creating one is the "encryption with private key"? – Manish Adhikari Jun 22 '21 at 12:20
  • Another problem you have is that you never encrypt anything with private key? You may sign it, but encrypting with private key does not happen. In most schemes I know of, encryption with private key cannot even be defined – Manish Adhikari Jun 22 '21 at 12:21
  • Or it is sent over TLS/SSL?Anyway, it is redundant because use of server issued certificates for clients, (server creates a trusted CA for application usage) used with mutual authentication does the job just fine or should I say much better – Manish Adhikari Jun 22 '21 at 12:32
  • @ManishAdhikari This is intended to be used in addition to TLS. It should be used for the server to authenticate the client. TLS is used for the client to authenticate the server, therefore it is not redundant if I am not mistaken. I think you are missing the point a little though. The only reason for this is that the server should not be able to generate a 2fa-token, only to verify it. This should also prevent attackers from being able to get into the system by generating tokens themselves in case of a data leak, which is the same reason for why we don't store passwords in plain text. – Gamer2015 Jun 22 '21 at 12:55
  • You cannot completely prevent that in case both your private key and your TOTP secret key leaks. Second is for server to not be able to generate 2fa-token it should be simple token plus a signature on it, not something "encrypted with private key". It is a dangerous but worryingly common misconception that something can be authenticated by encrypting it with private key and verified by decrypting with public key. Also you need to be careful about replay attacks but I guess limiting time window works – Manish Adhikari Jun 22 '21 at 16:00
  • @ManishAdhikari I am aware that I cannot completely prevent this, but the private key would need to leak from the client. You're right, "signing" is better than "encrypting" in this case. I think replay attacks are already prevented from TLS though, so I would like to not worry about it here ... – Gamer2015 Jun 23 '21 at 11:59
  • Yes, without TLS, replays would be possible even with limited time window. I was thinking about old leaked tokens – Manish Adhikari Jun 24 '21 at 04:40

4 Answers4

11

There are a few issues with your scheme that I can think of:

  • the server would have to store several keys per user, where the current scheme needs just one secret to be stored for multiple client authenticators
  • the authentication scheme shifts the responsibility of generating and maintaining the secret to the client, not the server, even though the server is the authenticating party
  • the client (the now-responsible-party) has no way of notifying the authenticating party that a key is invalid
  • it's over-engineered since a client-side PKI scheme could replace the entire authentication process
  • client-side key management is more difficult than it appears

Your scheme is perfectly acceptable and is a well-known authentication design pattern that has been in use in mutual authentication SSH for decades. It is not fit-for-purpose for the goals of MFA, however.

"Why is this acceptable?" "Why is it, or any other such alternative, not used?"

Because TOTP supports a password and is not considered to have the same level of sensitivity.

schroeder
  • 123,438
  • 55
  • 284
  • 319
  • 1
    Thank you for the in-depth answer as well as mentioning considerations when creating authentication factors. – Gamer2015 Jun 22 '21 at 10:46
7

2FA is not one thing. It's a general concept, where you have two factors. The factors may be a shared secret you have, or it may be a PKI certificate the user has. It may be U2F.

If you have concerns over the database of secrets, don't use TOTP; use U2F or some other 2FA which doesn't require you to have this database.

The shared secret is a weakness in TOTP. But TOTP is also easy and cheap to add, and well supported by many different devices. This makes it easy to implement.

Security is nearly always a tradeoff between usability, cost and security. TOTP is cheap to implement, well supported, and mitigates many of the problems with password reuse and phishing. It's not perfect; the secret can be leaked or copied.

More secure standards such as U2F or PKI is more expensive, as the user is likely to require a hardware device - but U2F will provide a higher level of security.

vidarlo
  • 12,850
  • 2
  • 35
  • 47
  • Thank you for your answer as well as mentioning alternatives to TOTP. I don't quite understand how U2F removes the necessity to store a secret on the server but I'm sure that is something I can read up on somewhere on the internet. – Gamer2015 Jun 22 '21 at 10:49
  • 2
    [It's public key cryptography](https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-overview-v1.2-ps-20170411.html). The U2F device creates a private and public key, and gives the remote server the public key. The private key never leaves the U2F device. An attacker that has the public key can't reconstruct the corresponding private key, and won't be able to authenticate. – vidarlo Jun 22 '21 at 11:23
  • This is exactly what i was expecting, thanks for providing a source for further information! – Gamer2015 Jun 22 '21 at 12:58
  • @Gamer2015 Have you considered PIV smart card instead of TOTP? – NetServOps Jun 22 '21 at 13:00
  • @vidarlo To nitpick: the per-site private key is then wrapped by symmetric encryption with a secret key inside the U2F token then sent to the site and stored there. The only thing stored by the token is the wrapping key. An attacker that stole the server's database can't reconstruct the private key because they can't unwrap it. It's a nifty trick also used by TPM. – user71659 Jun 22 '21 at 21:23
  • @user71659 sure, this is actually a trick to avoid having to store data on board. [It's even documented](https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-overview-v1.2-ps-20170411.html#allowing-for-inexpensive-u2f-devices) :) – vidarlo Jun 22 '21 at 21:40
2

the secret is stored on both the client and the server. This in turn means, that anyone with access to the database (and a key for it) knows the 2fa-secret of all the users. Why is this acceptable? Storing plaintext passwords has been deemed unacceptable a long time ago.

There is a conceptual mistake in the question. When a site gets cracked/pwned/leaked, it's considered gone. Sites get cracked every day, including any sort of valuable personal information. The very reason why we protect passwords is that because they are reused and chosen by user. TOTPs are not. If my own secure password is C0rr€ct B4ttery $tapl€ Hors€, it's likely that I use it both on http://buy.cheap.pizza and chase.com, the former obviously using a lot less security measures. Once it's stolen, it can be used to try to attack my chase.com account with direct financial consequences

Passwords are an asset. A valuable asset.

2FA is used to protect the account from an attacker doing malicious things after compromising the first factor, which happens to be the password and passwords often happen to leak.

The key is that the TOTP secret is chosen by the server, not by the client. So if the server gets cracked and TOTP leaks, it can be used only on the very same site. But it can't be reused to log in to github.com, gmail.com etc. as it is unique.

Indeed, certificate authentication is stronger. Indeed, FIDO U2F is going to that direction. But the question starts from a mistaken assumption.

usr-local-ΕΨΗΕΛΩΝ
  • 5,310
  • 2
  • 17
  • 35
-2

Why not use a public key and only the client has the private key? Just like U2F does. Kind of like sending a crypto transaction.

I don't see why U2F needs to be on a hardware device, when it also can just be an app that does the same, like a mobile wallet.

Just have an option of password, pin code, swipe code, or fingerprint to open the app.

Just having U2F without a physical hardware key would be a million times better than a regular authentication. Because websites get hacked all the time and they hold everyone's logins and private codes.

And if they are able to get them without anyone noticing, they could just monitor and leech off accounts for a long time before anyone figures it out.

It looks like someone is working on a U2F app already, which they are calling WebAuthn

https://www.w3.org/TR/webauthn/#note-pkcredscope

schroeder
  • 123,438
  • 55
  • 284
  • 319
Smotty
  • 1
  • You are talking about an entire authentication scheme. The question is about TOTP, specifically. All the other answers t alk about either U2F or replacement authentication schemes. And "WebAuthn" is not an "app"; it's a standard that has multiple implementations. – schroeder May 22 '22 at 15:35
  • Hello Smotty, welcome to the community. Please try to answer the question rather than doing what you're doing. – Sir Muffington May 22 '22 at 19:17