28 Followers
·
Follow

Image for post
Image for post

I know what you’re thinking, that I’m another one of those people out there that think they can roll their own protocols better than the contributors of SSL/TLS. I’m here to tell you that I am not! I’ve recently stumbled upon a really nice framework that allows to you safely define your own protocol that is still supported by the best practices used in Diffie-Hellman cryptography. The name of the framework is called “The Noise Protocol”.

The Rationale

So why would you want to use some other framework when you already have TLS/SSL? Well it really comes down to a question of what type of application you are building that needs strong encryption over a network. If you’re starting from scratch, and you have custom requirements, starting with something like TLS can feel a bit heavy weight. There is a lot of documentation and so many options, it can take a really long time to figure out what parts of the protocol you need to accomplish your goals. Whereas with the Noise Protocol Framework, you can define exactly what you need from the ground up without removing a bunch of features you don’t need. This also means that you can keep your messages very small and succinct without a bunch of headers and other data that you aren’t taking advantage of. And in other cases, existing protocols such as TLS, SSH, and IPsec may not be capable of accomplishing the protocol goals you’ve defined for your application. With Noise, you can accomplish many different protocol goals with a single framework by starting from the ground up. Additionally, Noise attempts to keep things simple. Simplicity, some would argue, is even more secure than protocols that carry around a bunch of extra data that is ultimately not being used by the protocol itself. By having all these other flags and options in a protocol, an attacker has a much larger surface area to attack the protocol.

The Noise Framework attempts to balance the need for some application designers to pick and choose the exact features they need by providing small layers that can be combined to create a complex and rich feature set for a protocol design. You can think of Noise as a bunch of legos that can be combined in interesting and useful ways, but that are easy enough to put together that you don’t have to be an expert in cryptography to navigate the API. Noise was designed such that you can create a huge number of protocols with relative ease and can be tailored for your specific use case.

Let’s see an example!

If you’re anything like me, sometimes words are really boring and code is less so, so let’s take a look at a use case that I dreamed up!

I love doing electronic and software projects around the house. Before I had discovered peer-to-peer libraries, I would use services like AWS IoT and some other centralized infrastructure so I could chat with my devices even when I wasn’t connected to my local area network. However, more recently I was introduced to a really simple and easy to use P2P networking stack called hyperswarm. It’s really easy to use and to setup, so it was a good starting point for me to use to communicate with random devices that I setup around my house. There is one problem though, there is no secure communication built around this library. That’s ok because we have the noise protocol to the rescue! I wanted to setup a situation where I knew what the public key was for the device, but the device didn’t know about my remote device. That way, as long as I knew the public key to my home device, I could establish a connection. Furthermore, I could secure the device even more with a preshared key (psk).

So the first step was reading through the specs of the noise protocol framework and figuring out how to setup the pattern. So in noise protocol speak, my device is going to called the “responder” and the client device (i.e. my phone) is going to be the “initiator”. So I want the case where my device (i.e. my responder) doesn’t know anything about my client (it doesn’t know its public key) and my phone or laptop (or my initiator) knows the public key for the device.

So let’s take a look how to set things up. First and foremost we need to instantiate the web assembly object:

Next we realize what pattern we want to use, which is going to be XK. The first position is for the initiator, and in this case it is X. X means that the initiator is going to transmit its key to the responder. The second position, which is K for the responder, means that the static key is known to the initiator. This is a great start for security, but ideally for this case you would want mutual authentication, i.e. both the responder and the initiator know about each other’s static keys. So the first handshake can be just to send a validation e-mail to the device system admin for approval, once that has been done, the responder could record the initiator’s keys in a database on disk so that mutual authentication can be done to perform more sensitive transmissions such as opening a garage door or watering a plant. The pattern for that type of communication is “KK”. So this is the next bit of code we need to define our protocol:

I’m not going to go into the details regarding each of these algorithms, so feel free to look them up!

For our test case, I’m not going to go through the trouble of setting up a client and server, I’m simply going to create everything in one file to keep the code as succinct as possible. But in the code, you can imagine what parts you would put in the device, and what parts you would in the client.

So now that we have established our patterns and our encryption, hashing, and cipher algorithms, we can create the keys for both the responder and the initiator:

Since this is just an example, we would probably want to store these keys for each the responder and the client and load them in next time so we don’t have to establish a new key pair each time.

Next we can setup the handshake. Keep in mind that the way we named our protocol matters. You’ll notice that if you try to change the patter to something like “Jackie Chan”, you will get an error!

Now we can get into setting up the actual handshake on both sides. You’ll notice that in the following code I don’t include a prologue or a pre shared key. Adding these things will definitely make your communication even more secure.

Now that we have initialized both parties, we are ready to begin the handshake. Like I mentioned above, this would normally be done over some sort of a network socket. I wrote a simple loop that demonstrates how the handshake is done. Basically the responder and the initiator send messages back and forth to each other until the “Split” state is reached or if there is handshake error, which could mean that someone is attempting to connect that doesn’t have the proper information! The code below demonstrates this:

Once the handshake is complete, we can now begin sharing information with forward secrecy! Pretty sweet right? This is an example of how to pass messages back and forth:

Conclusion

Well with a little bit of work, and a lot of fun we can create our own secure protocols to meet the needs for our own projects! We don’t have to rely on protocols that have thousands of options we don’t need and we can easily build support for protocols that haven’t been implemented in other libraries. I’m definitely looking forward to using this protocol more for future projects.

Also, I realize that the code syntax highlighting is lacking in Medium, so you can find the entire code listing on my github page: https://github.com/AcidLeroy/noise-example.

Thanks for reading and happy hacking!!

Written by

Computer Engineer for the heck of it

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store