I'd like for two machines on a network to be able to prove to each other that they both have knowledge of a pre-shared secret, without revealing the secret to each other. Let's assume that all traffic over the connection between the parties, A and B, is encrypted.
Here are the steps I'm currently imagining:
1. A->B: nonce_A, hash(nonce_A || secret_key)
- B checks that they can produce the same hash using
nonce_A
- even if B can produce the hash, it doesn't yet prove A knows the key (e.g.could be a replay attack)
2. B->A: nonce_B, hash(nonce_B || nonce_A || secret_key)
- A checks that they can produce the same hash using the nonces and key
- if
nonce_B == nonce_A
, the handshake fails - A now knows B knows the secret key
3. A->B: hash(nonce_A || nonce_B || secret_key)
- B checks that they can produce the same hash using the nonces and key
- B now knows A knows the secret key
4. Both sides know the key!
My understanding is that this protects against replay attacks (since a fresh nonce is used each time) and also against reflection attacks (since the hash must include BOTH parties' nonces).
Are there any security issues in this approach?
(I'm also curious if there are any existing RFC or similar for doing this.)
A
to detect a replay attempt. And thanks for the references. $\endgroup$