[nanomsg] Re: nanomsg and encryption

  • From: Alex Elsayed <eternaleye@xxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx
  • Date: Wed, 20 Mar 2013 04:42:36 -0700

Sorry for not threading this properly, but I'd been reading in the archives 
and so just signed up.

As a disclaimer, I am not a security professional. I have, however, read 
enough of their writings to shy away from trying to build secure protocols 
from scratch, and use existing tested ones instead. I also try to keep up with 
recent developments as to what *is* existing and tested.

Anyway, there are a couple of things I feel really need to be said.

First of all, *please* do not attempt to implement an entirely new protocol 
for encryption and authentication. Here There Be Dragons. The number of 
revisions (and vulnerabilities thereof) that SSL/TLS has gone through should 
be a powerful illustration of that - with first the Netscape developers, and 
then the IETF putting their expertise in it, it's *still* had a difficult time 
getting it right.

Secondly, TLS as you have been discussing (stream-based over TCP) is is *not* 
the only option in the suite of protocols under the TLS umbrella. DTLS 
(Datagram TLS) may be specifically interesting, because it's intended to be 
used over UDP, DCCP, and various other datagram-based protocols.

This means that rather than encapsulating nanomsg in TLS over TCP, you now 
have two additional options:

a.) Encapsulate nanomsg in DTLS over UDP/epgm/other datagram transports
b.) Define a DTLS encapsulation over nanomsg, just as was done for SCTP, DCCP, 
and a few other protocols; and handle the actual encryption in the nanomsg 
library (because scaling DTLS would likely benefit from knowledge of the 
topology).

The latter seems particularly attractive in this case, because it allows you 
to use the same DTLS code regardless of transport, and use nanomsg's existing 
ability to do record separation.

I would recommend *against* making the encryption end-to-end, because doing so 
means the routing information would remain completely unencrypted, and would 
thus be vulnerable to an attacker *modifying* it, resulting in misdelivery or 
nondelivery. Instead, decrypting/encrypting at each hop in the scalability 
layer and allowing the user to handle any end-to-end concerns is likely the 
sanest route.

If you *really* want end to end, without sacrificing security, you would 
likely have to do it twice - an inner channel for the user data, and an outer 
one that protects both that channel and the routing data.

Thirdly, regarding authentication, TLS 1.2 has support for what is called 
"AEAD" (Authenticated Encryption with Associated Data), and even in older 
versions used a MAC (Message Authentication Code) to verify the integrity of 
the message.

This means that the initial negotiation, which can verify the identity of both 
the client *and* the server even though only the latter is commonly used by 
browsers, the entire communication channel is secured to the same degree. Not 
just confidential, but authenticated. AES in the Galois Counter Mode method of 
operation is a strong example. This protects against any modification of 
messages, rather than only them being read.

The negotiation also supports multiple methods - X.509 public key is far from 
the only option; there is also SRP [a zero-knowledge password proof, that 
authenticates by the client having a password and the server having a verifier 
roughly equivalent to a salted hash, without either sending the password over 
the wire or even allowing the server to figure out what the password is], 
OpenPGP public keys, and several others.

OpenSSL (and GnuTLS, although since nanomsg is BSD-licensed that is likely 
unattractive) supports DTLS, although OpenSSL does not support SRP. There is a 
draft in progress for an alternative to SRP called AugPAKE which may have 
better luck - SRP had some patent FUD early on that seems to have inhibited 
its spread, even though it was later resolved.


Other related posts: