Update: original problem description
I am developing a client-server system for configuration updates. The system handles update tasks. An update task is initiated on a server; multiple clients then need to connect to the server to negotiate their updates within this task. A task can be initiated either manually of programmatically, and can be done either via CLI or via REST interface.
The requirements:
- It should be absolutely easy for the end user to do those tasks;
- Connections between clients and server should be secure, in the sense of that the whole communication should be authenticated, encrypted, protected against violations of message integrity or any other attacks, such as replays.
I will appreciate any suggestions to solve this task simply and efficiently.
The solution I have in mind currently is to generate a PSK on a server, and use then this PSK on the clients for connections. For that I have developed a symmetric key protocol that will mutually authenticate and establish a new short-living session key between two parties that have a pre-shared key. Unfortunately, I have not found any existing protocol that would fit my purposes, so I quickly devised my own. Would greatly appreciate your feedback on the protocol, or otherwise any advice to find something that already exists.
Notation:
C = Client
S = Server
K = pre-shared key between C and S
ENC(K, m) = message m encrypted with key K; encryption function is AES-256-CBC
MAC(K, m) = a message-authentication code of message m, computed using key K
rnd = random value
c1 = client challenge (randomly generated by the client)
c2 = server challenge (randomly generated by the server)
K' = short-living session key
The protocol:
C -> S : em = ENC(K, (rnd, c1)), MAC(K, em)
S -> C : em = ENC(K, (c2, c1)), MAC(K, em)
C -> S : em = ENC(K, (c1, c2)), MAC(K, em)
Further session messages are encrypted with session key K' = c1 + K + c2:
* -> * : em = ENC(K', m), MAC(K', em)
Thanks a lot for your help!
Update: Rationale for using PSK instead of private/public keys. Simplicity of usage. A tool is run on a server, and generates a unique PSK automatically, which the user then needs to manually or programmatically transfer to the clients he wants to connect. For the user this is much easier than using public-key cryptography.
Update: Rationale for having session keys in addition to PSK. In the system I am working on, A PSK establishes a limited-time trust between a server and multiple clients. The underlying protocol is for configuration management, and there should be a protection against replay attacks. IF I were just to use the same PSK to encrypt different sessions, THEN it could be possible, as far as I see, just to record and then replay a session to achieve another (unauthorized) configuration update, which would be bad. Usage of session keys precludes this scenario.