Public key authenticated encryption and why you want it (Part I)

If you read or watch any recent tutorial on symmetric (or “secret key”) cryptography, one lesson should be clear: in 2018 if you want to encrypt something you’d better use authenticated encryption. This not only hides the content of a message, but also ensures that the message was sent by one of the parties that has access to the shared secret key and that it hasn’t been tampered with. It turns out that without these additional guarantees (integrity and authenticity), the contents of a message often does not remain secret for long either.

In the old days these properties were considered separate. If you wanted to encrypt you used an unauthenticated cipher, and if you wanted to authenticate you used a MAC. If you wanted both (and it became clear over time that you almost always did), then you had to combine the cipher and the MAC and hope that the combination was secure. Mostly, it wasn’t. You see, it turns out to be less than straightforward to combine a cipher and a MAC. There is one approach that is (almost) always secure: Encrypt-then-MAC (EtM). First you encrypt the message using the cipher and then you authenticate the encrypted ciphertext using the MAC. But it took quite a long time before that was well known, and a lot of mistakes were made along the way.

In order to prevent these mistakes, cryptographers adopted the combined goal of authenticated encryption and developed cipher modes that combined both functions in one, such as AES-GCM or ChaCha20-Poly1305. Such modes treat the problem as a unified whole rather than as separate pieces to be combined by the user. Now there are many high quality authenticated encryption modes, and so it is relatively easy to do the right thing.

Contrast this with the current situation for public key encryption. In this setting, the security goal is usually seen as confidentiality with ciphertext integrity (also known as IND-CCA security – indistinguishability under a chosen ciphertext attack). This goal ensures confidentiality and integrity, but without sender authentication. The receiver can be sure that the contents are private and that the message has not been tampered with, but they do not know who the sender is. For instance, in this (generally very good) article from Matthew Green, he argues that IND-CCA2 is the correct security definition in a public key setting (compared to authenticated encryption), because in the public key setting “I should be able to (safely) decrypt messages from anyone”. I disagree with this goal however. I argue that in almost all cases I want to know who sent me a message, and I want to make a trust decision based on that information.

Consider Green’s example of Apple’s iMessage service, or even email. I don’t actually want anybody at all to be able to send me a message, as mostly they just send me spam. Even in the rare case that I am willing to accept an email from anybody, I want to be able to positively identify who they are before I decide act on its contents. Even in the public key setting, I almost always want (sender) authentication as well as confidentiality and integrity. I want public key authenticated encryption!

I am slightly mischaracterising Prof. Green’s blog somewhat here. He is not actually arguing (I think) that authentication is not important, but rather arguing a more subtle point: that the combination of (chosen plaintext) confidentiality with sender authentication (in the form of signatures) is not sufficient to prevent chosen ciphertext attacks in the public key setting like it was in the symmetric setting, and that therefore we want IND-CCA2 security. I completely agree with this, but my point is that I still want sender authentication in 99% of cases. In other words, I still want authenticated encryption but rather than combining authentication with a simple CPA-secure cipher as I can in the symmetric setting, I need to combine authentication with a CCA-secure cipher in the public key setting.

These kinds of subtleties are why I would like cryptographers to focus more on authenticated encryption in the public key setting. As was the case for symmetric key crypto, combining authentication with public key encryption is far from straightforward. I have seen developers replace a symmetric authenticated encryption algorithm used for session cookies with RSA-OAEP, and be completely unaware that now anybody at all can now forge a valid session. They needed authentication but didn’t understand the security properties of the crypto. It is easy to see why developers get confused as many standards present symmetric authenticated encryption algorithms and public key encryption algorithms (without authentication) as if they were equivalent and interchangeable.

I said earlier that the security goal for public key encryption is almost always presented as IND-CCA security. There is one prominent exception: NaCl. If you’ve not head of NaCl (pronounced “salt”, geddit?), it is a well-respected cryptography library developed by Daniel Bernstein. NaCl clearly documents the security goal of its crypto_box function as public key authenticated encryption. As a result, it is much easier to construct a secure system with NaCl than by trying to combine typical public key encryption and signature schemes.

In Part II, we will look at how to achieve public key authenticated encryption in practice, including how NaCl does it (and potential drawbacks). In Part III, we will then consider some changes to JOSE and other standards to clarify and improve the security properties on offer.

Author: Neil Madden

Security Director at ForgeRock. Experienced software engineer with a PhD in computer science. Interested in application security, applied cryptography, logic programming and intelligent agents.