Score:2

Mutual authorization using a pre-shared key

sz flag

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.)

Steffen Ullrich avatar
kp flag
This question is off-topic here and on-topic at [cryptography.se]. *"I'm also curious if there are any existing RFC or similar for doing this."* - sure, just search for [pre shared key authentication rfc](https://www.google.com/search?q=pre+shared+key+authentication+rfc) and you'll find standards for PSK authentication in IPSec/IKE, EAP-PSK, PSK in TLS ...
Marc Ilunga avatar
tr flag
One nitpick with this protocol is that it doesn't really authenticate the parties. Maybe that is desired? If it is not desired, then the issue is that an attacker can force party A into a session with itself while A thinks it completed the session with B. Depending on the application, this might not be so good. The protocol described is very close to the MAP1 protocol from Bellare and Rogaway (check it out). Another thing, using a Pseudo Random Function might be a better choice here. Though currently it's not too bad because the key is prepended.
Kira avatar
sz flag
Thanks Marc, that's a great point. I think if each side had even a short-lived "session identifier" that was used in conjunction with the nonce, it would allow `A` to detect a replay attempt. And thanks for the references.
Kira avatar
sz flag
Marc, what is the danger in not using a PRF instead of (inside of?) the hash function?
Score:1
mx flag

First off, if you can, just use something standard like TLS-PSK which is designed to do exactly this and is hard to mess up.

If you do want to roll your own crypto, symmetric stuff is definitely the most foolproof place to start.

simplifying the protocol

Simplest protocol is:

secret key sk, A and B pick nonces N_a,N_b

  • A-->B N_a
  • B-->A N_b,Hash(N_a || N_b || sk || bytes("b-->a"))
  • A-->B Hash(N_a || N_b || sk || bytes("a-->b"))

When deriving keys, pseudorandom values or challenge responses, just add a string to the hash that's unlikely to be reused elsewhere.

If you need to derive encryption keys, just do K_a2b=Hash(N_a || N_b || sk || bytes("K_a2b")) or similar. Adding strings to the value to be hashed is pretty standard for adding context to get different values out of a hash function or key derivation function.

A few things to keep in mind

Are you are using /dev/urandom or your platform's equivalent secure random byte source? If not, nonce values could be predictable.

If the random number generator in A or B breaks and nonces start repeating, hash comparisons can be vulnerable to a timing attack.

If you use your language's = operator to compare the hash value you receive from the peer to a value calculated locally your code will take longer to reject an answer if more bytes of the hash match. With enough timing measurements an attacker can determine the entire value. Always use something like https://docs.python.org/3/library/hmac.html#hmac.compare_digest when doing byte string comparisons in crypto code.

Alternatively, if you can't find a constant time comparison somewhere in your standard library, you can do this:

def masked_compare(a,b):
    rand=get_random_bytes(16)
    return hash(rand+a)==hash(rand+b)

It's not constant time but it doesn't allow for timing based extraction of the correct answer.

Kira avatar
sz flag
Thank you for your notes Richard! Also, TLS-PSK does a LOT more than just verifying each party knows a pre-shared key. I'm trying to see what exists that does only this piece.
Kira avatar
sz flag
I think this is vulnerable to the same replay attack Marc outlined in the comment to my question post. If `bytes("a-->b")` were actual session/permanent identities rather than a static string literal, I think it would be avoided.
Richard Thiessen avatar
mx flag
Relay attack, not Replay, but yes. There's no session establishment happening here, at least I'd hope not. All you get is a liveness guarantee. Mallory needs to relay messages between two people who know the secrets. If you trust the underlying network (bad idea unless you're dealing with a secure VPN like Wireguard or similar.) then you could bind (EG:10.1.2.3 is Alice and 10.2.3.4 is Bob) as you suggest. If this is a prelude to sensitive communication then STOP IMMIDIATELY and use TLS or similar to encrypt that communication.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.