That's a question I already asked myself many times but I have yet to find a satisfying answer, the problem I see with low level encryption (at least in TLS case) is that at this level the library has no idea what is transmitted and where a message starts and ends, my understanding is that it justs use an internal buffer and send it when full or on timeout. I really feel that having the user code encrypt/decrypt the data would be more efficient since at this level we know what a message is and could decide what to encrypt and how based on this. The problem is of course different with nanomsg/zmq since the library knows where a message starts and ends and could potentially do a better job that with a standard tcp socket. My knowledge in encryption algorithms is rather low so I cannot really comment on what you propose but not relying on packets ordering or potential losses seems like a good idea :) On 4 March 2013 09:20, Martin Sustrik <sustrik@xxxxxxxxxx> wrote: > 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 > >