The Dark Side of End-to-End Encryption
How Public Key Exchange Vulnerabilities Can Compromise Your Privacy
I recently became aware of the Contact Key Verification feature in iMessage. That discovery led me to learn some of the ways that end-to-end encryption (E2EE) can defy our expectations. If that sounds like something you’ve never pondered about, then read this scenario below from the Electronic Frontier Foundation’s Surveillance Self-Defense - https://ssd.eff.org/module/key-verification).
Suppose someone claiming to be your friend Esra’a sends you a chat request on an encrypted messenger application like WhatsApp or Signal. Even though you think your messenger is using Esra’a’s public key, you may be encrypting your messages using a key that came from a different person entirely—which means this fake Esra’a will be able to decode all your future messages.
In the age of online communication, E2EE has become a staple of secure messaging and email services. The promise of E2EE is to provide complete confidentiality and integrity for all communications, ensuring that only the intended recipient can access the data being exchanged. However, like any security feature, E2EE is not foolproof. One critical vulnerability is in the way public keys are exchanged between devices.
How does End-to-End Encryption Work for Messaging?
E2EE is a way to keep your online communications private and secure. Think of it like sending a secret letter. When you send an encrypted message, only the sender and recipient can read it. Each user generates a pair of keys: a private key and a corresponding public key. Public keys are shared widely and are not confidential. Senders use the public keys of the recipient to encrypt messages. Messages encrypted with a public key can only be decrypted with the matching private key.
Let’s think about what happens when you send a message through a platform like iMessage, WhatsApp or Signal.
You draft a message on your phone to a friend - let’s call that friend Bob.
Your phone requests Bob’s public key from the messaging platform.
Your message is encrypted on your device using Bob’s public key. This ensures that only Bob, who is in possession of the matching private key, can decrypt and read your message.
The encrypted message is then sent to the Bob’s phone.
Bob’s phone uses Bob’s private key, which is stored on his phone, to decrypt the message you sent.
Bob can read the message.
The Vulnerability in Public Key Exchange
The key vulnerability in the E2EE process as described above is in Step 2 when your phone requests Bob’s public key from the messaging platform. How do you know that you have Bob’s public key and not the public key of someone impersonating Bob?
Apple has a great blog post about this problem and how it can be solved with a centralized key directory service. Note that they are talking about iMessage which uses E2EE. https://security.apple.com/blog/imessage-contact-key-verification
Typically, the provider of an end-to-end encrypted messaging service operates a key directory service, which maps a user’s identifier — such as an email address or phone number — to public keys for each of their registered devices.
When Alice wants to send Bob a message, Alice’s device contacts the key directory service and requests the list of public keys for Bob’s devices. Alice’s device can then start an encrypted conversation using the encryption keys it received for Bob and send him a message using the transport specified by the protocol.
The use of the key directory service allows all iMessage users to gain access to any public key they need to send an E2EE iMessage. The blog post continues and lays out the specific vulnerability.
While a key directory service like Apple’s Identity Directory Service (IDS) addresses key discovery, it is a single point of failure in the security model. If a powerful adversary were to compromise a key directory service, the service could start returning compromised keys — public keys for which the adversary controls the private keys — which would allow the adversary to intercept or passively monitor encrypted messages.
Here Apple is talking about a Man-in-the-Middle Attack where an attacker can intercept the public keys exchanged between two parties and use them to establish a fake-secure communication channel. This fake-secure communication channel is not really secure at all. Both Alice and Bob believe it is secure but it really is not. Alice believes she is communicating with Bob and Bob believes he is communicating with Alice, but they both are communicating with the attacker! Furthermore, this Man-in-the-Middle Attack is impossible for Alice or Bob to detect.
Even Signal clearly spells out the problem of impersonation in their specification - https://signal.org/docs/specifications/x3dh/#authentication.
the parties may compare their identity public keys … through some authenticated channel. For example, they may compare public key fingerprints manually, or by scanning a QR code… If authentication is not performed, the parties receive no cryptographic guarantee as to who they are communicating with.
The parties “may” compare their identity public keys to gain a “guarantee” as to who they are communication with. I’m going to rephrase this - without comparing public keys or their fingerprints, you have no guarantee you are communicating with your intended recipient.
This impersonation vulnerability highlights a crucial limitation in E2EE: while it provides confidentiality for individual messages, it doesn't guarantee the integrity of the communication channel itself. An attacker can intercept or manipulate data in transit, compromising the overall security of the exchange.
Mitigating the Risk - An Unpractical Approach
Out-of-bound public key verification is the way to know you are using the correct public keys for the people you are messaging with. Let’s break that down.
Out-of-bound means you need to use a communication channel different from the one you are trying to establish the security of. This means, you cannot use Signal messaging to verify the public keys for your Signal messages and you cannot use iMessage to verify the public keys for your iMessage messages. Until a communication channel has been verified to be secure, you have to assume it is compromised.
Public key verification means you are comparing the public key your device has for the recipient with the recipient themselves confirming it is correct. This verification is bi-directional as you would need to verify for that other person that they have the correct public key for you.
Imagine now, trying to bi-directionally verify the public keys for each person you want to have secure E2EE messaging with. In reality, you can’t do this directly because you can’t even access your public keys on your device. All of this encryption happens behind the scenes. But even if you could access those public keys, you’d be hard pressed to verify a key that is multiple hundreds of bits long.
Mitigating the Risk - Purpose Built Features
A 2018 paper looked at the usability of public key verification for Signal specifically - https://www.usenix.org/conference/soups2018/presentation/vaziripour. The title of the paper was pithy “Action Needed! Helping Users Find and Complete the Authentication Ceremony in Signal”, but the conclusion was concise:
The security guarantees of secure messaging applications are contingent upon users performing an authentication ceremony, which typically involves verifying the fingerprints of encryption keys.
They continue:
The common conclusion of [prior research] is that users are vulnerable to attacks and cannot locate or perform the authentication ceremony without sufficient instruction. This is largely due to users’ incomplete mental model of threats and usability problems within secure messaging applications
At this point, you should have a much better mental model of how E2EE works with messaging platforms and the need for public key verification.
Below are some resources for some of the messaging platforms and how to perform public key verification. Note that each platform calls it something different.
iMessage - Contact Key Verification. https://support.apple.com/en-us/118246
Signal - Safety Numbers. https://signal.org/blog/safety-number-updates/
WhatsApp - Key Transparency. https://engineering.fb.com/2023/04/13/security/whatsapp-key-transparency/
In general, you’ll never be verifying the correctness of the entire public key - it is too cumbersome. Instead, you’ll be verifying using a “fingerprint” of the public key. Again, the different messaging platforms call them different things, but essentially, it is something more human usable that can accomplish the goal of public key verification.
There are a few things to keep in mind when performing these “authentication ceremonies” using fingerprints of your public keys.
Fingerprints aren’t secret. Just as your public key is not secret, the fingerprint of your public key is not secret.
Fingerprints should be verified before the communication channel can be considered secure. If not, you have no guarantee that your intended recipient is the only one able to read your messages.
Fingerprints must be verified over an authentic and tamper-proof channel. Follow the instructions for the messaging platform, but in general, don’t text the fingerprint over WhatsApp if you are trying to secure WhatsApp.
Conclusion
End-to-end encryption remains a vital component of online security. But it's essential to acknowledge the baseline assumptions we take for granted when assuming end-to-end encryption guarantees our privacy. Exchange of public keys is the bedrock on which the security and privacy benefits of end-to-end encryption are built.
I hope you learned something today. If you use a secure messaging app (which you should) take some time to use whatever “authentication ceremony” it provides. Share the word with your friends, family, and community - especially those that are vulnerable because of their geography, identity, political ideology, or status.
Let’s ensure that our online communications remain secure and private.