Recall that current forms of two-factor authentication (2FA) rely on:

  • Something you know, i.e. your password

  • Something you have, i.e. your one-time password (OTP) generator on a trusted device

The procedure is as follows:

  • Client sends username (public)
  • Client sends password (private)
  • Client sends otp = HashOTP(client_seed, time())
  • Server looks up salt, salted_password_hash, and seed for username
  • Server compares HashPW(password, salt) against salted_password_hash
  • Server compares HashOTP(seed, time()) against otp
  • Client is authenticated iff all comparisons succeed.

The idea, of course, is that even if all the transmitted information is intercepted by an attacker, the attacker is unable to authenticate because he does not have the client_seed to generate a subsequently valid otp.

So far so good, except that interception of password permanently reduces 2FA to 1FA.

"Permanently" because the user will have no idea his password is compromised, and will therefore have no reason to change it.

So, ironically, not only is otp a "one-time password", but so is password itself. (!)

(Now, at this point, I'm sure some of you are ready to close the question, thinking, "But TLS should have protected the password during transit, and if the client itself is compromised, then the problem is invalid!" If you're in that camp, well, realize that's not how the world works. A passive keylogger on the client could be secretly recording everything but the actual stolen credentials are likely to stay unused until a while after, when the user is unlikely to notice it. So it makes sense to render any such keylogger useless if possible.)

Given that the user will reuse password without even knowing that his 2FA is really 1FA, a theft of his device is all that stands between him and his account, and he is likely to think he is safe because he has no idea his password might have been compromised.

How, then, can we address this?

Initially I was thinking that the user could type his password into his trusted OTP generator and generate a single one-time password that will authenticate him without ever having to send his actual password.

But now it seems to me the server would need to know the password itself in order for this approach to work. In other words, it defeats the storing of hashed passwords—i.e., a server-side leak will now reduce all users' 2FA to 1FA, instead of a client-side leak.

Basically, it almost seems that 2FA is fundamentally 'single-use': any attacker with read-only access will reduce 2FA to 1FA, and the client and server can remain indefinitely unaware.

But I don't know if this is really the case.

Can we keep the two-factor nature of 2FA even after a client or server data leak, without otherwise weakening the system's security? How (or why not)?

  • $\begingroup$ Why are you referring to the OTP and password functions as trapdoor functions? That implies that some secret information would let you reverse them, but those two types of functions are designed to be completely irreversible. $\endgroup$ Commented Feb 27, 2017 at 4:18
  • $\begingroup$ @JosephSible: Yeah, wrong word choice on my part... fixed, thanks. $\endgroup$
    – user541686
    Commented Feb 27, 2017 at 4:35

2 Answers 2


If you use asymmetric cryptography you can make it work. The trusted device stores a private key and salt the user will type his password and it will get hashed with salt and get encrypted/signed and the result sent to server which has public key and the salted hashed password. The main problem is the trusted device now sends something much larger then the common short tokens used today. Also public key crypto is more computationally expensive, we know how to make the server side cheap but not both sides. A server breach doesn't expose the private key, a trusted device breach doesn't expose the password and a loss of password doesn't expose the private key.

  • $\begingroup$ Elliptic curve asymmetric crypto isn't as computationally expensive. $\endgroup$
    – Awn
    Commented Feb 27, 2017 at 5:17
  • $\begingroup$ Faster then rsa, and shorter messages as well, but still slower then symmetric options and still longer messages then I would care to type. $\endgroup$
    – Meir Maor
    Commented Feb 27, 2017 at 5:27
  • $\begingroup$ +1 thanks! To clarify something: are you saying anything about symmetric crypto (i.e. that it can't work) or are you making no claims about that? $\endgroup$
    – user541686
    Commented Feb 27, 2017 at 7:06
  • 1
    $\begingroup$ In order to say it can't work I would need a more formal definition of the requirements. You described a problem and I suggested something I'm fairly certain is secure and addresses the concerns. $\endgroup$
    – Meir Maor
    Commented Feb 27, 2017 at 20:49

A PIN-protected smart card will do the job. The PIN is something you know, the card is something you have.

It's somewhat expensive, since you will also need a reader with integrated PIN-pad (to foil keyloggers), but some banks do use this method to authenticate online transactions.

Here is an example from NatWest: https://www.youtube.com/watch?v=pSykGdRyDMM


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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