I have three participants:

  1. A client A in possession of the public key Kpub
  2. A login server S in possession of the private key Kpriv
  3. Game servers B (B1, B2 etc)
  4. S and all B may share a finite number of secrets before, but not after the exchange. This is basically a scalability measure. If S would need to send data to B in order to create a key for A, then that makes scalability harder.
  5. A and B should not use asymmetric key exchange, to reduce CPU impact on game servers.

The current scheme works roughly like this:

Client A, Login Server S, Game Server B

(1) A → S : { Na, A }Kpub

Ksa ← { Na, Ns, A, Saltenc }PBKDF2

Ksasign ← { Na, Ns, A, Saltsign }PBKDF2

M ← IV || HMAC(IV, { Na, A, Ttimestamp }Ksb)Ksbsign || { Na, A, Ttimestamp }Ksb

(2) S ➝ A : { Ns, IV, HMAC(IV, { Ns, M }Ksa)Ksasign, { Ns, M }Ksa }

(3) A ➝ B : { N'a, M }

(4) B ➝ A : { Nb }

Kab ← { Na, N'a Nb, Saltenc }PBKDF2

Kabsign ← { Na, N'a Nb, Saltsign }PBKDF2

Encryption proceeds using Kab, signing each with Kabsign and keeping a running counter with each packet.

I'm aware of some weaknesses in this as it is written which I intend to fix, but you should get the general idea of what I'm doing:

  1. Client A requests an encrypted packet containing it's nonce Na securely from S.
  2. S returns the packet encrypted packet in a way that A can assure the packet is from S.
  3. Client A gives the packet in the clear to B (since no one but B or S can decrypt it), who unpacks the nonce and can create a shared key Kab. This shared key is then used for the remaining communication, such as authenticating or registering A. (Of course, there are nonces thrown in, so each new request for a Kab will produce new keys)

So this is basically just for ensuring confidentiality of the channel between A and B.

The nice thing is that if the connection is dropped or logged out, then A can use M again for new connections to B without keys being repeated.

Now, given the difficulty getting a protocol right, it would be awesome to use a well-known vetted protocol for this.

Does anyone know of an alternative that works in a similar manner that I could replace it with?


The aim here is exchange keys in order to set up a secure channel between A and B. This is because at this point A might not be registered at B, so will need a way to register securely without anyone eavesdropping on that registration.

This is why the Kerberos model doesn't work - A might be entirely unknown to S and B.

I'm seeing the following possible threats I want to avoid:

  1. Someone eavesdrops on A's registration and is then able to login as A.
  2. Someone eavesdrops on A's login and is then able to play as A.
  3. Someone eavesdrops on A's login and is able to login as A by replaying the first messages. This will cause A to get disconnected even if the attacker can't continue the conversation.
  4. If, due to network issues, many clients simultaneously disconnect and then reconnect, the reconnect is sufficiently costly that B is unable to process all connects.
  5. Someone mounts a man-in-the-middle attack and is able to randomly change what A does.
  6. Someone redirects traffic to a server B' without A being aware of it.
  7. A DDoS acting like (4) should only affect the server attacked.

Or more succinctly:

  • A can safely play - any covert manipulation will be detected by client and/or server and no-one can steal A's credentials without accessing the data in the client directly.
  • The server topology is not sensitive to DoS / DDoS.
  • 1
    I'm not sure what you mean by (rephrasing): "... if the connection is dropped or logged out, client can request new secure session while it's still valid". I think there's a problem right there, no? Could you also share with us reasons for dropping your previously suggested protocol? It might help finding an answer. ;)
    – TildalWave
    Jun 21 '13 at 9:37
  • @TildalWave basically the "session" M contains a nonce only known to the client and anyone who can decrypt M. Using this secret nonce together with public nonces from A and B, we can create new keys without having to retrieve a new session every time. Since public nonces from A and B are new for every connect, we can assure ourselves that our keys are different for each connect, even if the "session" used is the same.
    – Nuoji
    Jun 21 '13 at 10:00
  • @TildalWave the "previously suggested protocol" is exactly what I detail above. So basically this is asking if there's an alternative to my own hand-rolled protocol.
    – Nuoji
    Jun 21 '13 at 10:02
  • Who calculates K(ab) ? A and B? If so how do they get the same Salt(enc) value?
    – jcopenha
    Jun 21 '13 at 15:51
  • 1
    1) Sounds somewhat similar to kerberos. 2) I think you're overestimating the cost of asymmetric crypto. You can easily do several thousand key-exchanges per second. Jun 22 '13 at 8:09

I can't understand what your requirements are -- strangely, you don't seem to have listed the security requirements, or threat model, or what you are trying to achieve -- but the obvious approach would be to use a Kerberos-like (Needham-Schroeder-style) protocol. Those schemes give S a way to help A and B establish a secure channel between them. They can be implemented using just symmetric-key cryptography, so they should perform and scale extremely well.

In straightforward Needham-Schroeder, we assume that initially S and A share a symmetric key (KS,A) known only to them, and that S and B share a symmetric key (KS,B) known only to them. After execution of the protocol, A and B receive a session key (KA,B) that's known only to them, and that A and B can use to communicate securely (to establish a secure channel between them). Both A and B receive assurances of each other's identity. The Needham-Schroeder protocol has been well-studied; for instance, early versions had a subtle flaw, which was subsequently discovered and corrected in later research by Gavin Lowe.

If there is some reason why the server needs to authenticate itself using public-key cryptography, Needham-Schroeder can probably be modified in a straightforward way to support that. (For instance, A could connect to S using TLS or something similar; then S could continue from there to help A and B establish a secure session key KA,B, by sending KA,B to A, and also giving A an encrypted version of the session key, encrypted in such a way that B can decrypt it and verify its freshness.)

  • Actually I think you identified it. The first part of my protocol is very similar to TLS (with the client already holding the server cert, and the second part to Needham-Schroeder. But surely someone must have married those two before?
    – Nuoji
    Jun 23 '13 at 6:57

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.