In order to make a scalable end to end encrypted messaging service on a bare-bones budget I’ve looked into several libraries: GPGME, SequoiaPGP, and Libsodium. I’m hopping off the treadmill of progress for the time being since new ones keep coming out. Google now has Tink which is supposed to be harder to screw up so hopefully someone else can check that out. What these incredibly talented cryptographers and programmers are creating has allowed me, a lowly software glue technician to build some very cool stuff.
TLDR: I’m plugging my experimental encryption command line program that I made using libsodium, a cryptography library. Use it as inspiration for your own projects. Agginym Key Utility.
When I was learning how usual end to end encrypted systems worked everything seemed in one way or another to boil down to these six actions from which a state in a distributed system can be inferred. The distributed system I’m talking about consists of the connections between you, me, some rando across the world, our messages and the myriad of interactions between them. The six actions are:
- Create encryption and signing keys of some kind.
- Share your keys in some way
- Sign a message where you say you know about it in some way. This creates a signature.
- Verify a signature by using the signer’s public key. This tells you that the signer is aware of the message in some way.
- Encrypt a message for an individual using their public key. This creates an encrypted message.
- Decrypt a message from an individual using your own private key. This reveals the original sent message.
In order to learn how these libraries worked I made a c++ wrapper using defaults I would want. Then I made another…then another. This happened over several months. Hopefully you’ll be able to gain something from my pain.
What I found after doing it three times is that all of the libraries accomplish the highlighted steps above. It doesn’t really matter too much which one you use so long as you follow expert advice and use the encryption settings they say you should use. There are lots of them and thankfully they like to talk!
To that end if you want the fastest cryptography library that takes of some hard stuff like which algorithm to use just use Libsodium. In my somewhat complicated scenario of chain verification it was about 5x the speed of SequoiaPGP. I could have been doing many things wrong but there are probably costs associated with maintaining compatibility with PGP. Libsodium has no need to do that.
If you need to interact with GPG systems for some reason, use SequoiaPGP. It’s 2-4 times as fast as synchronous GPGME from my testing. Other pretty smart people have found performance results that point in that direction as well. There is an OpenPGP.js library which is very stable and allows you to work with the web, (extension or native application only, websites are never to be trusted). Keep in mind that you’ll have to deal with preventing legacy usage.
If you want to stick with GNU all the way down, use GPGME. That’s the only reason I can find to stick with it. You’re essentially going to the shell every single time you use a library function. It kinda slows things down.
Now that that’s been said, here’s part of what I’ve been working on using the tech above: Agginym Key Utility. It supports the creation of key pairs and the signing, verifying, encrypting and decrypting of messages/files. Give a try and if you’re willing to go through the effort, tell me how it sucks or doesn’t suck. If you need utilities that work and most people are sure that they work, just use Minisign for signing and age for encryption.