# Would this authentication on a Diffie-Hellmann-key-exchanged channel work?

Before I ask my question, let me say that I don't know the math behind OTR, so I don't know if the process of authentication in OTR is any similar to this.

• Alice and Bob have exchanged keys using Diffie-Hellman key exchange
• There's a man-in-the-middle - Eve.
• This is the encryption "circuit": Alice -- e_alice -- Eve -- e_bob -- Bob
• Both Alice and Bob use e to express the encryption key they use.
• Thus in conditions where there is no MitM, e_alice == e_bob
• Alice wants to verify that there is no MitM, so uses a verification question (and an answer) (like OTR in XMPP):

Q: Do you have a cat?

A: Yes

Note: Obviously use strong values for A. Don't ask about the presence of a cat, but rather cat's name (ideally if it's a unique name containing numbers and special characters) :P

• Alice sends Q to Bob
• Bob sends hash(e_bob+A). hash is any safe hashing algorithm, e_bob is the encryption key Bob uses, and A is the answer, salt in this context.
• Alice compares received == hash(e_alice+A). In case this is true, there is no MitM.

In this context:

• The hashing algorithm for zero-knowledge-proof
• The encryption keys are a pre-shared (by the key exchange) secret
• The answer is used as salt (while being another pre-shared secret), so Eve can't think: "Oh look, that's a sha1 hash. Let's try to crack it. Oh look it's our encryption key -- that's a no-go"
• Possibly add additional encoding like base64 to minimize chance of hashed contents being in wordlists. (hash(base64(e_bob+A)))

Question: Are there any serious vulnerabilities, or would this work for authentication for insecure encrypted channels?

• Don't call the secret a salt. It's not a salt, it should have the properties of a secret key to be secure. For SHA256 for instance, it should have 256 bits (although you could get away with a lot less). You should definitely restrict the amount of connection attempts if you use an actual cats name; those are easy to iterate over. If you have a secret with almost enough bits of randomness, use a key strengthening function such as PBKDF2, bcrypt or scrypt. – Maarten Bodewes Oct 24 '16 at 21:41
• The base 64 encoding doesn't do anything to avoid the issue described above. Once the attacker knows that encoding is used, then the attacker can simply perform the encoding as well. Encoding schemes in general do not add security to any scheme, ever. – Maarten Bodewes Oct 24 '16 at 21:43
• @MaartenBodewes Well, the base64 doesn't prevent brute force attack, but it prevents rainbow tables. – Samuel Shifterovich Oct 24 '16 at 21:43
• You mean use the key strenghtening likehash(e+key_strenghtening_algorithm(A))? – Samuel Shifterovich Oct 24 '16 at 21:52
• No, it doesn't protect against rainbow tables, it prevents one specific rainbow table. And you don't need to. If you use ephemeral-ephemeral DH then you'd generate a new key pair and thus a new $e$ every time as well. Now that will prevent rainbow tables to occur (I don't think it is possible for the other party to force a specific $e$ by sending a specific & valid public key). And yes, that scheme could work (I'd use a HMAC instead of a hash as fgrieu already indicated though). – Maarten Bodewes Oct 24 '16 at 23:30

In the question as it stands now, nothing prevents Eve to relay Do you have a cat? to Bob, get the answer A = Yes by testing A for Yes or No against hash(e_bob+A) obtained from Bob, then send hash(e_alice+A) to Alice and defeat the protocol.
If only the "strong value" is unknown to Eve, it acts as a secret key in an ad-hoc protocol (for something academic we'd want to use this "strong value" as key to HMAC of message e)