[nanomsg] nanomsg and encryption

  • From: Martin Sustrik <sustrik@xxxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx
  • Date: Mon, 04 Mar 2013 09:20:10 +0100

Hi all,

I've spent some time thinking about adding encryption (and possibly other security features) to nanomsg. Here are my thoughts. Comments would be appreciated.

There are two main ways to go:

First, we can add new encrypted transports to the set of existing transports. For example, tls:// could work like tcp:// with encryption added. Let's call this hop-by-hop encryption.

Disadvantages:

1. Works only for a particular transport type. Implementing tls:// does help with encrypting TCP traffic, but doesn't help with multicast traffic.

2. Intermediate nodes in the topology (devices) have to be trusted, so that they can decrypt the message, check the header and do the routing decision.

Advantages:

None of the unsolved questions, as discussed below, applies.

Second, encryption can be done on top of nanomsg. Sender would encrypt the message, then send it to nanomsg. Receiver would retrieve the message from nanomsg, then decrypt it. Let's call this model end-to-end encryption.

Advantages:

1. Works for all possible transport types (inproc, ipc, tcp, udp, multicast etc.)

2. Intermediate nodes don't have to be trusted. Message headers are not encrypted anyway, so routing decisions can be made straight away.

Disadvantages/unsolved problems:

1. Encryption is done on per-message basis, so existing mechanism for encrypting TCP stream or UDP packets in libraries like OpenSSL cannot be re-used. It should be also taken into account, that some messages may be missed, re-ordered etc.

2. Given that encryption doesn't happen between 2 TCP endpoint, rather between N topology endpoints, there are additional security concerns to be taken into account. For example, usage of symmetrical key is not scalable: As the set of endpoints grows, it becomes more likely that one of the endpoint owners will leak the key and thus compromise the whole topology.

3. To solve the above problem, asymmetrical topologies, such as pub/sub, fan-in or fan-out may benefit from using asymmetrical encryption (public/private keys). For example, PUB socket can encrypt using a private key and SUB sockets can decrypt using a public key. The problem with that is that it makes encryption algorithm dependent on messaging pattern (symmetrical encryption for pair and bus patterns; asymmetrical encryption for pub/sub, fan-in, fan-out; no idea about what to use for req/rep...)

4. Once we move past encryption to making sure that the message wasn't faked, additional security concerns arise. In the most rigorous case, each member of the topology would have to have its own private key to sign the messages with.

5. Finally, content-based routing in pub/sub wouldn't work. The intermediate nodes (devices) have no access to the message payload so they would not be able to do message filtering. Easy way out would be to add "topic" field to the message header and thus prevent it from being encrypted.

That's about it. Any comments would be appreciated.

Finally, here's a way that libraries like OpenSSL can be used for encrypting nanomsg messages (CBC-style), rather than TCP bytestream or UDP packets (once again, comments on the algorithm would be appreciated):

When socket is created, generate a (cryptographically) random key and set counter to zero. For each message the counter would be incremented. Then, by encrypting the counter using the random key we'll get an IV. A different, shared key would be used, in combination with the IV, to encrypt the message. IV would be prepended to the encrypted message and sent to the topology.

The receiving endpoints would use the IV stored at the beginning of the message, together with the shared key, to decrypt the message.

The idea behind the algorithm is to make IV unpredictable and thus to avoid chosen-plaintext attack. Encrypting the counter makes the result unpredictable within a single lifetime of a socket. Choosing the key to encrypt the counter randomly make the IV unpredictable when socket is closed and re-opened.

Using the encrypted counter, rather that generating a random IV for each message makes the algorithm viable for scenarios with high message rate. If the IVs were generated randomly, we would soon run out of available randomness on the system. If, on the other hand, we had used pseudo-random IVs, it would make the scheme vulnerable to chosen plaintext attack.

One important property is that decryption of a message is completely independent of any other message. Thus, it works even if messages are lost, re-ordered, messages for different sources are interleaved etc.

Martin

Other related posts: