# public key cryptography and authentication for cross-platform network application

I'm developing network based application for control and telemetry on Linux based embedded system. I'm using ZMQ network library and Google Protocol Buffers serialization library for communication purposes.

I took a look at CurveZMQ however there is no official binding for C++ and I do not want to mess up my implementation with CZMQ binding. Therefore I decided that I do not want to use CurveZMQ extension and I want to use some external library for authentication and encryption.

I want to apply following security measurements to my application/system:

1. "CURVE" security mechanism, to give me strong encryption on data, and (as far as we know) unbreakable authentication.
2. Client public key authentication.
3. I would appriciate library with binding to many programming languages because my client application is going to run on many different platforms.

Nice to have:

1. Curve25519 elliptic curve cryptography (ECC) algorithm.

I believe I can encapsulate handshake messages in my Protocol Buffers messages.. So basically the idea is to establish secure tunnel between server and client and somehow enforce client and server authentication. Below you can find how my unsecure system is working and where I imagine to put encryption layer. I do not have any idea how to solve authentication issue at the moment.

Here is the big picture of my not secure system.

 ______________________                       ______________________
|                      |                     |                      |  APPLICATION
|        client        |                     |        server        |  LAYER
|      application     |                     |      application     |
|______________________|                     |______________________|
/\      ||                                   /\      ||
||      ||                                   ||      ||
______||______\/______                       ______||______\/______
|                      |                     |                      |  SERIALIZATION
|       protobuf       |                     |       protobuf       |  DESERIALIZATION
|______________________|                     |______________________|  LAYER
/\      ||                                   /\      ||
||      ||                                   ||      ||
______||______\/______                       ______||______\/______
|                      |                     |                      |  TRANSPORT
| zmq_socket.send(...) |-------------------->| zmq_socket.recv(...) |  LAYER
|                      |      (TCP/IP)       |                      |
| zmq_socket.recv(...) |<--------------------| zmq_socket.send(...) |
|______________________|                     |______________________|
python client                                  C++ server


Here is how I imagine my secure system.

 ______________________                       ______________________
|                      |                     |                      |  APPLICATION
|        client        |                     |        server        |  LAYER
|      application     |                     |      application     |
|______________________|                     |______________________|
/\      ||                                   /\      ||
||      ||                                   ||      ||
______||______\/______                       ______||______\/______
|                      |                     |                      |  SERIALIZATION
|       protobuf       |                     |       protobuf       |  DESERIALIZATION
|______________________|                     |______________________|  LAYER
/\      ||                                   /\      ||
||      ||                                   ||      ||
______||______\/______                       ______||______\/______
|                      |                     |                      |  ENCRYPTION
|      encryption      |                     |      encryption      |  LAYER
|______________________|                     |______________________|
/\      ||                                   /\      ||
||      ||                                   ||      ||
______||______\/______                       ______||______\/______
|                      |                     |                      |  TRANSPORT
| zmq_socket.send(...) |-------------------->| zmq_socket.recv(...) |  LAYER
|                      |      (TCP/IP)       |                      |
| zmq_socket.recv(...) |<--------------------| zmq_socket.send(...) |
|______________________|                     |______________________|
python client                                  C++ server


Basically I need help with making my system secure. Could you help me with that?

• Anything speaking against using TLS v1.2 for the channel? (Sorry TLS has no Curve25519 support yet) – SEJPM Aug 17 '15 at 9:20
• Is it independent from TPC/IP socket implementation? Curve25519 is just nice to have. I'm public key cryptography rookie so I'm looking to advises and other algorithms might be fine as well. – Krystian Sakowski Aug 17 '15 at 9:24
• I'm optimistic towards NaCl library which has binding for C++ and python and few other languages which at this point is good enough for me. I've found nice example of public key encryption with the help of this library. It seems quite easy however I still do not know how to put all (authentication + encryption) security measurements together. Here is the link to mentioned example pynacl.readthedocs.org/en/latest/public – Krystian Sakowski Aug 17 '15 at 9:24
• TLS requires TCP but the implementations are independent. (If you need TLS over UDP consider DTLS) There are many TLS implementations out there and they should be compatible with each other. TLS will create you a provably secure authenticated channel while using certificates or pre-shared keys for entity authentication. Example libraries are: s2n, GnuTLS, BoringSSL, LibreSSL, OpenSSL, NSS, ... – SEJPM Aug 17 '15 at 9:34
• I'm using ZMQ over TCP/IP. This library makes packet oriented messaging over TCP/IP. But TCP/IP properties remains because ZMQ is over TCP/IP. My understanding is that TLS should work fine with my solution. Am I right? – Krystian Sakowski Aug 17 '15 at 10:03

TL;DR: use (D)TLS. This is exactly the kind of problem it was meant to solve.

If possible, use cert pinning too (if you get to deploy the code on both ends of the channel, this should be possible).

The general rule is: don't design your own crypto protocol unless both of the following apply.

1. You have done a detailed review of what exists already and have a good reason why existing protocols are not good enough.

2. You are, or will hire, a professional cryptographer. Better still, a team of cryptographers.

Think of some of the recent attacks on SSL/TLS like the POODLE padding oracle attack. If you design your own protocol, how can you be sure you don't have side-channel, padding-oracle, replay, man-in-the-middle, malleability or similar attacks? (If any of those words are gibberish to you, see point 2. above.)

If something as widely used and reviewed as TLS turns out to have crypto problems every now and then, your own protocol is likely to have the same problems and then some.

If you really need something new, libsodium is the closest I know to a "just add water" solution. Key generation/distribution is actually the harder problem but if you're in charge of deploying code to all devices involved then you can generate the keys up front. Each device should end up with a keypair and every device that needs to talk to device X needs a copy of the public key for device X. For example, if you write an app that needs to talk to your server, include a copy of the server public key in the app.

Then just use authenticated encryption everywhere.