I am writing a system where the user must log in with two passwords: a normal password (salted and hashed, stored in database), and a special password where the user needs to type only some letters, e.g. "please type the second, third and last letter of your password".

How can one design that system to support the second password?

Idea 1: store the password in plaintext. Of course not.

Idea 2: Store each character separately, salted and hashed. Bad because if the attacker knows the salt, it only takes a few dozen guesses to bruteforce the character.

Is there any other way?


The two passwords have to be typed at the same time, like so:

hang seng bank 2FA alternative - second password

The purposes of the second password are:

  • Defeat the attacker who looks over your shoulder while you type the password, or a keylogger.
  • Defeat the password manager in your browser, when someone like your family member can log in to your account if you chose to save your password in the browser.
  • Provide a simple alternative to 2FA when the user is not accessing extremely sensitive information, so we don't bother them to retrieve their hardware one-time password generator (which they also have).
  • 2
    what is the purpose of the 2nd password? is it like a "security question" that adds on top of the password, or does this new password grant access to elevated permissions that the first password does not? – schroeder Sep 21 '18 at 11:31
  • 1. Do not use a password for additional things, doing so will like reduce the security. 2. "salted and hashed" is not secure. When saving a password verifier just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead use a function such as PBKDF2, Rfc2898DeriveBytes, Argon2, password_hash, Bcrypt or similar functions with about a 100ms duration. The point is to make the attacker spend substantial of time finding passwords by brute force. – zaph Sep 21 '18 at 20:43
  • 1
    If the "special password" is an alternate to the "normal" password this is horribly insecure, it effectively shortens the password reducing the security of the password. "Schneier's Law": "Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break." That means don't create your own security sc hemes, use well understood and better methods. – zaph Sep 21 '18 at 20:55

You can't - at least not in software, for reasons given by Matthew.

If you have a five character password with a-z, that's 26*26*26*26*26, or 11881376 possibilities. However, if you can probe one character at a time, it's 26+26+26+26+26, or 130 possibilities.

Even for long, complex, passwords this reduces the amount of work that has to be done to trivial levels.

In addition it's bad security. People should use password managers, to have unique passwords everywhere. Password managers do not support this kind of queries. And even if it's a typed password, it's difficult, as many people rely on muscle memory to enter passwords. I wouldn't be able to give you the third character of my password without typing it out and checking.

  • Yeah, one of the goals of the second "partial" password is to defeat password managers, to reduce the chances of an attacker who gets full physical access to the machine. In other words, to prevent your friend from logging in on your laptop while you are not looking. Back to the topic - is it really not possible at all, with some hacks? The implementation that I've seen (as a user) only allows 8 characters in that "partial" password. – user123540 Oct 22 '18 at 3:44
  • Let's say we generate salted hashes for each possible combination of the three random letters of the password that the user has to type (1+2+3, 1+2+4, 1+2+5...). Let's say the hashing function is very expensive too, like 1 second. That would make it marginally more difficult to bruteforce. Perhaps there are some other hacks? – user123540 Oct 22 '18 at 3:44
  • 2
    @k48 you've still reduced the complexity from n^y, to n*y. And for what purpose? It's not user friendly at all, and it's not secure. Use a normal password and put 2FA on top. TOTP can be implemented fairly easily and with low cost. – vidarlo Oct 22 '18 at 4:35

Use a Hardware Security Module (HSM) which is effectively write-only for the full password, and which generates the parts required. The flow in this case is that your app asks the HSM for a verification step, it returns a set of expected letters and some form of identified for the request, the user provides those letters, the app sends them to the HSM, and the HSM returns either "yes" or "no", depending on whether they are correct. The HSM should require the same set of letters to be provided for that account until the user provides them, or the account is locked out, to avoid an attacker with partial knowledge of the password being able to log in by refreshing until they get characters they do know. This method should be safe, given a reliable HSM, but is likely to also be expensive.

Storing the plain text password or hashed individual characters both allow an attacker able to access the database table to find the full password with a predictable (low) amount of effort. Similarly, hashing each possible group of characters results in a small potential search space, even if every group is hashed with a unique salt (brute forcing three characters is not hard, even with a long salt, since the salt is fixed for each one). Encrypting the secret password increases the effort required, but only slightly: if you use the initial password (appropriately stretched) as the key, you defeat the concept of needing two pieces of information to log in. If you use anything which is stored on the server, the attacker potentially has access to the key, so can obtain the passwords.

  • 3
    While the HSM idea is a solid solution, it cannot be overstated how costly such an architecture would be in both money and programming. We should know the costs of the risks in order to know whether the HSM costs make sense. – schroeder Sep 21 '18 at 12:15
  • The answer make guesses at what the OP is trying to accomplish given the lack of a complete description of the usage in the question. – zaph Sep 21 '18 at 20:57

Your Answer

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