End to end encryption (and keeping data secure) in Elixir apps

With more and more focus on privacy, and new laws possibly coming in…

“The principle of confidentiality should apply to current and future means of communication, including calls, internet access, instant messaging applications, email, internet phone calls and personal messaging provided through social media,” said a draft proposal from the European Parliament’s Committee on Civil Liberties, Justice, and Home Affairs.

…what options do we have for end-to-end encryption in Elixir? Have we got anything like attr_encrypted for instance? How would you go about it in Elixir? Please share any tips/advice/further reading etc :slight_smile:


I am not quite clear what you mean here. End to end encryption means that the client is fully responsible for encryption/decryption. Unless elixir is the end-node it will simply be a carrier of encrypted traffic and there is not so much you can do except not trying to leak to much meta data. But “anonymousation” is a much harder problem than end to end.

Good reading material is any secure crypto protocols which claim end to end. Like the signal protocol (Start here: https://en.wikipedia.org/wiki/Signal_Protocol).

The provided link seems to be about encrypting data in the database which might be a good idea in some cases but also has little to do with end to end.

1 Like

Built-in in Erlang (based on OpenSSL), we have the :crypto module.

But as @cmkarlsson astutely stated: When you are building a server application in Elixir, the encryption and decryption needs to happen at the client-side. Only when you are making a command-line tool or a native GUI application in Elixir could you do the encryption/decryption in Elixir directly.

1 Like

Thanks both. I thought there might have been something additional required on the message delivery system/server/Elixir.

What about storing all user data securely (encrypted) on the server - in case the server is compromised? What if someone stole the server or hard-drives for instance?

Yes, this may be important. There are various layers that are normally used here (my terminology is probably off so don’t pay too much attention to it;)):

  • Data at rest. All data at rest should always be encrypted. This means disk encryption and encryption of backups for example. I guess some work here could be done in erlang/elixir with for example DETS storage.

  • Encryption on database. This is normally provided by the database software and usually entails encrypted connection between application server and database and on-disk encryption. The benefit here is that queries, joins and search are still possible/fast but it also has limited protection and only protects in the case someone gets access to the data files on the database. Data is in the clear in memory in both database (but can be restricted to some database users in for example oracle) and application server.

  • Appliation Data encryption. You can have the application server encrypt the data so that it protected even in memory in most circumstances. However if you decrypt in software the data will be in the clear in memory which again requires good protection of your actual server instance. I think your attr_encryption link earlier is an example of this and they also state the drawbacks such as you can’t index, search or join data from the database. Unless you have a secure core for handling unencrypted data I think this is not worth it. Too many inconveniences for too little benefit.

For extra sensitive data you can use an HSM (hardware security module) which generate and encrypts and decrypts data. Data is only in the clear in the HSM and of course the client can also decrypt it. For high levels security you need hardware support both on the client and server. Like secure chipset, factory bootstrapped certificates and HSMs.

It is hard to get to “criminal enterprise” security and “nation state” is probably impossible.

In practice: Just don’t be the weakest link ;), eliminate all the “easy” access points

For erlang and elixir, you need to make sure you use secure connections (SSL) in and out of the server and make sure that the server is hardened, you may want to avoid distributed erlang (although I don’t have a rational for this but it seems like it could open up some attack surface).

If someone gets physical access (or even remote access) to the server it is very hard to protect your data. That is why end-to-end encryption is important. You cannot guarantee your data if it is in the clear anywhere between the two end-nodes. And unless you are really sure that you don’t have any MITM (man-in-the-middle) attacks during key exchange you can’t really be sure anyway :slight_smile:

You can play around with your own security protocols but it is full of hard things to solve that you normally don’t think about. My go to example is using a short-circuiting comparision for an Message Hash. Because it takes shorter time to compare a “broken” hash than a correct one you are open to timing attacks which may be able to compromise your protocol.


If the client is a web browser, isn’t end to end encryption a fiction? If the user executes javascript then a compromised server can send (and force the browser to execute) any malicious script. If the user doesn’t execute javascript, how will the decription happen?

If you have a client that doesn’t execute serverside code, then end-to-end encryption is of course useful.


Yes, this has historically been the problem with javascript security. Mostly because of delivery problems. If you can deliver the scripts in a secure way you can potentially have some security.

For example shipping javascript bundled with your application which is distributed through a secure channel (are app stored secure?)

1 Like

That seems as safe as it can be. You need to assume that the app download is secure and the user never upgrades (otherwise the upgrades need to be secured). If you can’t assume this, then nothing is secure :stuck_out_tongue:

I think the problem with app stores is that they can probably make funky stuff with your code without the user noticing if they want. I know nothing about mobile development, so I don’t know how easy it is to check that the binary downloaded to the phone is the same as the one you compile yourself. This is probably overly paranoid for most atfack vectors, of course.

1 Like

Thanks for the informative post Martin :023: I think the quoted bit above is what concerns me most - most of us don’t have the luxury of having our own data centres and I would imagine it would be relatively easy to get access to someone’s servers in one of the commercial providers.

I definitely need to read up some more on this!

1 Like

If I need end-to-end I just PGP my message, which can serve a variety of purposes, like:

Hash: SHA512

I can sign my messages, which proves I am who I say I am (if you have my public key or grab it from one of the online distributors).
Version: OpenPGP v2.0.72


Or I can encrypt a message to someone (in this case to my public key), and I can sign that encypted message too that way they know it is absolutely from me and I know that only they can read it:

Version: OpenPGP v2.0.72


And since it is all just text I can send it anywhere, here, email, etc… :slight_smile:

1 Like

I’m on about securing user data in our apps - user’s don’t want to be bogged down with complicated steps ^^ :stuck_out_tongue: - they just want to sign up to a service/social network then make a post and expect it to be safe :lol:

Well you could use the Keybase messenger, it uses your local PGP keys and users public keys to send messages between everyone, fully secure and built on known standards instead of weird new things. :wink:

1 Like