How End to End Encryption Can Protect Our Online Conversations

Howdy! It’s been quite some time since my last post. Recently I have had quite a few crazy ideas, and for some reason none of them really worked :D, so sadly I couldn’t share with you so much (I prefer sharing stuff which I know in-and-out, rather than reporting the experiments). Luckily, this week one of those weird ideas turned out to produce something fun (and valuable), so I decided to share it with you today.

I bet you have heard of “end-to-end encryption” or (E2EE), but I don’t think most of us really understand what it is and how it works. I got tired explaining to my friends why they need to use less of those unencrypted messaging apps (like the infamous Facebook Messenger) to move to solutions with more privacy, like Signal or Telegram. At the same time, I also got tired of those who believe that since some messaging app claims to have end-to-end encryption, their messages will be totally safe to send online. Both of these two arguments are, well, naive, though in different ways.

First, some quick words to explain what end-to-end encryption is: It’s the kind of encryption of messages from the sender, with the intention that no one, except the intended recipient of the message, will be able to decrypt and understand the messages (In case you wonder, even the sender of the message won’t be able to decrypt that message once it is encrypted). The way that can be achieved is using a key pair of cryptographic keys, which, in simpler language, means a pair of keys work in way that whatever gets locked by one can only be unlocked by the other. Everyone will give out one key of theirs to everyone else, while keeping the other key to themselves. The key that gets sent out is called “public key”, and the kept one is “private key”. When one person (e.g. you) wants to encrypt a message that is intended to someone else (your dad?), you will use your father’s public key to encrypt that message, which makes it decryptable by only who owns the equivalent private key, i.e. your father. (The reverse process can be used also in digitally signin documents, in which you sign with your private key, and everyone else verifies that the signature is valid by using your public key, but that is not the focus of this post).

Up to this point, I may have only rephrased to you, in as short and simple as I can, what anyone who knows how E2EE would say to you if you ask them, but you may not be very persuated that it is, in anyway, related to you. After all, you have had years, or even decades, sending and receiving messages online, and you still survive without any knowledge about E2EE. As much as I agree that it is a valid point, I bet that if you value your privacy, especially if you don’t like seeing dog images wherever you go just because you sent a message to your buddy saying “I’m like a dog.”, then you will be interested in limiting the probability that all your messages are read by some AI (or some real people) before they reach their final destinations. (Anyway I wouldn’t be surprised if you finish reading this post and still end up doing exactly what you’ve been doing so far. Some of my Facebook friends also have a habit of complaining all the time about how they’re advertised about some product for weeks just because they mentioned that with their friend on a chat, yet I still notice they make Facebook checkins wherever they go and use nothing but Facebook Messenger as their main messaging app).

Part A. Client-Server Model

Before coming to the part where two friends can talk with each other via the same messaging app, let’s discuss a little bit of how a message tends to be handled after you send it out from your phone. Clearly we cannot expect that the message will go directly to its recipient, since we can’t know beforehands where they are. Even if the recipient ends up to be your partner who is lying right next to you, your message will still need to reach some server, from which it will be redirected towards its final destination.

The following Python code illustrates that you making a simple server and a simple client, which can talk to each other. In real life, of course you won’t be interested in talking to whoever running at the server (if there’s any), but the underlying concept is similar: once server receives your message, it will redirect the message to your friend, and vice-verse.

This is a short demo gif:

Part B. Client-Server-Client

Now as we know that client and server can talk, we can ask the server to forward what it receives from one client to another client as requested. This is what happens when you send and receive messages on an application that doesn’t offer E2EE (like Facebook Messenger)

Here is how it looks like. Notice that whatever either side of the conversation says, the server can read with no issue.

Part C. Enters the End-to-End encryption

This is the same situation, but this time with E2EE. At the beginning of the conversation, each side of the clients generates a pair of crypto keys, and sends the public part to the server. The server understands the key, but as it should forward everything, the keys will reach the other client. From that point on, all messages are encrypted before sending out, which makes it impossible for the server to decrypt.

This is exactly the situation that we want: we can send our messages in whatever route available in the Internet, but only people on the ends of the conversation will be able to understand each other. It’s normally what is promised by those messaging services with E2EE.

Part D. When E2EE can be compromised.

Though Crypto hash is a very safe algorithm, which is said to require hundreds of years to crack, E2EE-enabled services can, at least in theory, be compromised. I can think of at least two ways:

1. The messages may not be really encrypted.

Since the messaging service produces both the client and server daemon, there’s no way users can make sure that the messages are really encrypted. All they can see is that their messages are sent from one end and received in another. Some sniffing technique can be used to catch the message in the middle to see if the message looks like it was encrypted, but that kind of “encryption” is easy to fake: for one thing, the client can use the same key to encrypt everyone’s message.

2. The private key may also have been sent to the server

Even if a key pair was really generated, and even if every message is encrypted using an unique-to-person public key, the client can still secretly send both the public and private keys to the server.

Here is a short demo. Notice that though the messages are encrypted and the server seem to struggle reading them at first, it will still be able to decrypt the message.

Conclusion?

So in the end, since there’s clearly ways to compromise the unbreakable E2EE, should we just stop using it altogether?

Well, yes and no.

Yes. You should not trust a messaging service entirely just because they claim to have E2EE, at least don’t trust them yet before they show you their source code. I do not mean to say that I’m sure any particular service provider is unethical that way, but the possibility is still there.

And No. Please don’t take that as an excuse to use those apps that don’t encrypt your messages. The bots will just love that.

In fact, since the problem with E2EE lies in the fact that the same service is used in both encrypting and sending message, you can simply eliminate that issue by encrypting the message yourself. That’s a bit of a hassle, but it will be safe.

All the code used in this post can be found here: https://github.com/lthh91/fictional-enigma

Below is a summary of everything we’ve talked about so far in video mode. Sorry for the auto-generated voice, despite having been working from home since March, I haven’t got a decent microphone at home yet.

Written by Huy Mai