I have a system where some clients communicate with a server. every client has its own name and role and some other parameters that sends these info to the server in every message and the server uses those info somehow...
All communications are encrypted with symmetric keys. I have a master key that only I and the server know it. A client's key is derived from the master key this way:

client1_key=hkdf(16, MASTER_KEY, 'client1')

a client sends its encrypted messages to the server along its name/key ID, so the server can reconstruct the client's encryption key from the master key and the client name and decrypt the message. Other info like client's role are contained within the encrypted part because I wanted to reveal only the minimum/absolutely necessary information in clear text communication.

a problem here is that with this scheme, a client can claim, with the exception of its own name, other parameters that don't really belong to is. e.g. it can send any role it wants to the server and the server has no way to verify that those parameters are relevant to that specific client.

my solution to this problem was generating an HMAC over all restricted parameters and sending it alogn the other info (client name and encrypted message) to the server by every client. so each client receives its own key and the accompanying hmac that restricts the key use:

key_use_hmac=hmac_sha256(MASTER_KEY, client_name||client_role||another_parameter...)

then at the server this hmac is recalculated after extracting the client's parameters from its decrypted message and compared with that sent along the message by that client, if they match, the message is accepted, else the message is rejected.

an example of a message sent to server by a client:

name=client1, key_use_hmac=xxxx, encrypted_message=xxxxxxxxxxx

only name and key_use_hmac are send in clear text (key_use_hmac could also be sent within the encrypted part, but i thought it is not necessary at all - am i correct?).

I want to know if my scheme is sound enough or not.
thank you!

  • $\begingroup$ Why are you using a home-brewed protocol? Why not use TLS? $\endgroup$
    – stromboli
    May 4, 2017 at 20:20
  • $\begingroup$ @stromboli it's not a home-brewed protocol. I devised it in a garage. $\endgroup$
    – user40602
    May 5, 2017 at 5:42

1 Answer 1


OK, so you have come up with your own key-authorization and transport encryption scheme.

The key authorization scheme is fine and and quite a standard solution. A similar approach is used on the web to ensure the user doesn't forge certain cookies.

The per-client key derivation and key management also looks good, but for the encryption there's a better solution than "plain" encryption:
TLS-PSK. (Transport Layer Security with Pre-Shared Keys)
In this case the client can claim an identity during the handshake and confirm it by owning and using the assigned pre-shared key. As a bonus the TLS implementation will take care of all the replay-protection and authentication issues and you will only leak the absolut minimal information during the handshake: the client's name. As an additional bonus you can combine PSK with ephemeral Diffie-Hellman ([EC]DHE) to gain forward secrecy and don't get your sessions' secrecy compromised just because the MASTER_KEY has been leaked at a later point in time.

  • $\begingroup$ My server is on a shared host, so I think it is not possible for me to use TLS-PSK. My program exchanges its messages with HTTP-POST method; No need to opening any port on the server or client, No need to obtaining and configuring SSL/TLS staff. Isn't it enough justification? $\endgroup$
    – user40602
    May 5, 2017 at 9:33
  • $\begingroup$ @user40602 you really want to do this over standard TLS then because otherwise you are likely vulnerable to replay attacks. $\endgroup$
    – SEJPM
    May 5, 2017 at 12:26
  • $\begingroup$ I have implemented replay prevention already. It was an important time consuming and complex part of my program. I used counters+nonce (a new nonce generated per each installation at both server and client sides). $\endgroup$
    – user40602
    May 5, 2017 at 12:33
  • 1
    $\begingroup$ @user40602 also note that using this on top of (standard, server-authenticated) TLS will also likely give you forward secrecy for free thereby limiting impact if the master key or a derived key gets leaked. $\endgroup$
    – SEJPM
    May 5, 2017 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.