Alice has a bank account number, but has forgotten which bank it is for. There are 4 banks, run by Bob, Carlos, David, and Eve.

She could find out by going to all of the banks and asking if they have the account number. However, if Eve learns Alice's account number, then Eve will go to Alice's actual bank and steal all of Alice's money.

Alice could hash the bank account number, and ask about the hash, but since the account number is only 8 digits, Eve could bruteforce the hash anyway. Then, Eve will go to Alice's bank and steal all of her money.

Alice could use a Zero Knowledge Proving Protocol, but how would the bank know which account number to check against without repeating the ZKPP for every account number? Each of them has thousands of customers.

Context: I'm writing a program to retrieve an encrypted copy of one's keys and friends-list for a project called Tox (http://wiki.tox.im/index.php/Proposal:Friendslist_Server). I'd like to make it automatically detect which server has it.

  • 2
    $\begingroup$ The problem here is that your identification token is also your authentication token, and worse, it only has an key space of approximately 27 bits. I don't see a way to create a secure scheme out of this. $\endgroup$
    – orlp
    Aug 8 '13 at 22:36
  • 1
    $\begingroup$ Can't you simply use the username for the lookup followed by a zero knowledge proof for the password hash? $\endgroup$ Aug 9 '13 at 11:32
  • $\begingroup$ I don't understand the constraints. What parts of the system can we modify? Can we modify both the client (the software Alice runs or the procedure Alice follows) and the server (the code that the banks run for authenticating Alice or that process they use to help Alice check about that account number)? If you can change both endpoints, why are you limited to just 8-digit account numbers: why can't you choose arbitrarily long account numbers? (Also, you later mention cryptographic keys. If we're talking about keys, those won't be 8 digits long and won't be brute-forceable, so which is it?) $\endgroup$
    – D.W.
    Aug 10 '13 at 0:58
  • $\begingroup$ If the account number is a capability that's all that's needed to withdraw all of the money from that account, then 8 digits isn't enough. If a bank has ten million customers, simple random guessing will succeed with probability 10%. So the problem as specified can't be quite right. Something smells like we don't have all the real requirements/constraints.... Can you try editing the question to tell us the real problem you have? $\endgroup$
    – D.W.
    Aug 10 '13 at 1:01
  • $\begingroup$ @D.W. What parts of the system can we modify? Any part, but banks won't participate in any system that will allow an impostor customer to learn account numbers. If a bank has ten million customers I specified how many customers the bank has in the question. we don't have all the real requirements I specified the context in the question. $\endgroup$
    – Nick ODell
    Aug 11 '13 at 3:56

Private Set Intersection

How about a private set intersection protocol?

The banks input is a set of all of their account numbers, the user's input is their account number (a single member set). The output could be given to the user, or the bank, or both, depending on your needs.

You would need a way to protect against guessing account numbers. For example, I could just keep submitting account numbers to one of the banks until I find a valid account at that bank. Or, the bank could put tons, and tons of accounts in their set that they don't actually own with the hopes that your account number will be in there and they can figure out your account.

Both would be fairly easy to protect against if the account numbers are fairly large (say 256 bits) and randomly generated. The probability of success would be greatly limited. You could further limit the bank from submitting overly large sets as I think the size of the set is probably not kept hidden.

Another possibility

Another possibility would be to develop a multiparty set intersection protocol using multiparty computation. Use the paper I linked to as a basis (it only supports 2 parties). That way all parties participate in the protocol at the same time. An MPC framework such as VIFF will be helpful.

The idea is that all banks would input their account databases, the user would input their account number, and you find which set contains the account number and return to the user the ID of that bank. If 2 banks are found to have that account, someone likely falsifying accounts and return $\bot$.


As nightcracker notes in the comments, the real problem in your bank scenario is that the account number is doing double duty as both an identification token and as an authentication token.

The solution is equally simple: make the account number public and use it only for identification. Have Alice's bank issue her another number (let's call it a PIN) that isn't required to identify her account, but is required to withdraw money from it.

Of course, if some of the other banks are untrustworthy, they might claim to have Alice's account and ask for her PIN, only to then use it to steal money from her real account. To prevent this, Alice could (as you suggest) use a zero-knowledge proof protocol to verify her PIN to her real bank without allowing an impostor bank to learn it. Since the bank does know Alice's account number, they can use it to look up Alice's account information and verify her PIN against it.

The same solution should work for your actual problem: use the username to identify the user and the password to authenticate her. For the authentication step, I'd suggest an augmented PAKE protocol such as SRP, which will allow the user to prove her knowledge of her password to the server without ever having to actually disclose said password (or anything equivalent to it) to anyone.

Ps. See also this recent similar question.

  • $\begingroup$ Problem with SRP is that an attacker who impersonates a server learns the password hash, enabling offline search. I'd look into socialist millionaire or something similar protocols. $\endgroup$ Aug 9 '13 at 11:34
  • $\begingroup$ @CodesInChaos: Wait, how does that work? Maybe I'm missing something simple, but I can't see any obvious way for a fake server to obtain the user's verifier from an SRP authentication attempt. Explain? (Anyway, a good way to mitigate such issues in practice is to use a key stretching KDF such as PBKDF2 to hash the password. That's a useful precaution anyway, in case a legitimate server gets compromised. The iteration count should generally be chosen so that the hashing process takes about 0.1 to 1 seconds on a typical client.) $\endgroup$ Aug 9 '13 at 11:53
  • $\begingroup$ If the server successfully impersonates a legitimate server(the OP's assumption is that this is possible) they learn the public key of the client. Knowing the public key allows a password guessing attack, which is only partially mitigated by using a good password hash. With socialist millionaire only signup and not login are vulnerable to this. $\endgroup$ Aug 9 '13 at 12:27
  • $\begingroup$ "account number is doing double duty as both an identification token and as an authentication token." Could you explain why this is bad? If the user can remember N bits for your application, is it better to use N/2 bits for identification and N/2 bits for authentication? $\endgroup$
    – Nick ODell
    Aug 9 '13 at 14:30
  • $\begingroup$ @Nick: I gave some reasons in this answer, but the real problem in your scenario is that, with a combined account identifier/authenticator, you have no way of referring to the account without also disclosing the information needed to access it. (As for your second question, I'd say the optimal choice would be to use $M$ bits for identification and $N-M$ bits for authentication, where $M$ is the minimum number of bits needed to uniquely identify the user.) $\endgroup$ Aug 9 '13 at 16:34

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.