Secure Identity Negotiation
I have recently started to work on a secure grpc gossip library with certificate rotation. The main idea was to regularly distribute new certificates over the gossip protocol. I quickly run into the problem that identity negotiation is required. I will explain the problem and my solution.
The gossip protocol should run on mutual TLS, mutual TLS is very hard without a certificate authority. There should be a way to authenticate a new node to the gossip network. A “registration service” is required where mutual TLS is not needed but regular TLS with a self-signed certificate. So we don’t trust the network there can be man-in-the-middle or replay attacks.
The problem:
Node 1 wants to know if node 2 is a friendly node.
How to achieve this on zero trust network?
Trial one: passphrase
I have started with the idea of a pre-shared passphrase but I give up on it quickly because if the network is not secure it is prone to man-in-the-middle attacks and replay attacks. I need something even if somebody able to see the whole communication, it should not be understood.
Trial two: RSA encrypted passphrase
I quickly moved to the idea of having asymmetrically encrypting my passphrase. Nodes will share the public key, private key, seed, and a passphrase. Node 1 will encrypt and send the passphrase and node 2 will decrypt and check the passphrase. Sounds good but how the node 2will know the node 1 is actually node 1. Somebody could have captured the message and replaying it.
Final Trial: RSA encrypted random message with echo
This time, nodes will share the public key, private key, seed, and a prefix. Node 1 will generate a random message, encrypt and send it to node 2. Node 2 will decrypt it, add pre-defined prefix and encrypt it again and send it back to node 1. Node 1 will decrypt it check it against the prefix and the random message sent. This way node 1 will be sure that it is talking to the right node, then node 1 will decide to send its current certificates.
This seems to be a good approach security-wise:
- Since the message is generated randomly for each negotiation session, it can not be replayed.
- All messages are random byte arrays so it is not possible to crack it with brute-forcing.
- Prefix makes requests and responses different for negotiation, so both sides are validated.
- Certificates used for encryption is not transferred on the wire.
You can find the readme and code example on the github:
I am not a security researcher so I would like to hear critics if there is a security issue with this approach, so comments are appreciated.