151

Frequently, we want to send messages that are (a) encrypted, so passive attackers can't discover the plaintext of the message, and (b) signed with a private-key digital signature, so active attackers can't make Alice think that a message came from Bob when it didn't.

Is it better to

  1. generate the digital signature from the (hashed) plaintext, and then encrypt a file containing both the plaintext message and the digital signature?
  2. encrypt the message first, and then generate a digital signature from the (hashed) encrypted file?
  3. combine encryption and public-key digital signatures in some other way?

A closely related earlier question (Should we MAC-then-encrypt or encrypt-then-MAC?) seems to focus on symmetric-key MAC authentication. As Robert I. Jr. asked earlier, do the same issues with (symmetric key) MAC-then-encrypt apply to (public key) sign-then-encrypt?

apaderno
  • 155
  • 7
David Cary
  • 5,664
  • 4
  • 21
  • 35
  • 1
    Existing answers are dated. See https://github.com/rweather/arduinolibs/issues/15#issuecomment-818950513 – tejasvi88 Dec 16 '21 at 11:43
  • @tejasvi88 I'm going to remove this comment as 1. I don't think it outdates the given answers and 2. you should make it an answer yourself instead rather than just providing a link in the comments. Of course, having a blanket statement like this is not advisable due to current answers getting updates or new answers getting posted. – Maarten Bodewes Mar 31 '24 at 22:42

7 Answers7

116

Assuming you are asking about public-key signatures + public-key encryption:

Short answer: I recommend sign-then-encrypt, but prepend the recipient's name to the message first.

Long answer: When Alice wants to send an authenticated message to Bob, she should sign and encrypt the message. In particular, she prepends Bob's name to the message, signs this using her private key, appends her signature to the message, encrypts the whole thing under Bob's public key, and sends the resulting ciphertext to Bob. Bob can decrypt, verify the signature, and confirm that this indeed came from Alice (or someone she shared her private key with). Make sure you use an IND-CCA2-secure public-key encryption scheme and a UF-CMA-secure public-key signature scheme (i.e., one that is secure against existential forgery attack).

Justification: The reason to do this is to defeat some subtle attacks. These attacks are not necessarily a problem in all scenarios, but it's best to harden the approach as much as possible. A complete explanation would take more space than is available here, but see below for a sketch of the reasoning.

For a detailed analysis about whether to sign first or encrypt first, the following is a good resource: Defective Sign & Encrypt in S/MIME, PKCS#7, MOSS, PEM, PGP, and XML.

I don't recommend encrypt-then-sign. It could work, but it has some subtle pitfalls in some contexts, because the signature does not prove that the sender was aware of the context of the plaintext. For instance, suppose Alice's SSH client sends the message "Dear SSH server, please append my public key to /root/.ssh/authorized_keys -- and you can know that I am authorized because I know the root password is lk23jas0" (encrypted then signed with Alice's public key), and the SSH server acts on it if the root password is correct. Then Eve can eavesdrop, capture this message, strip off Alice's signature, sign the ciphertext with Eve's own key, and send it to the SSH server, obtaining root-level access even though Eve didn't know the root password.

D.W.
  • 36,365
  • 13
  • 102
  • 187
  • I notice you write "IND-CCA2-secure public-key encryption". Is this as opposed to CCA2 SIM-NME' (www.iacr.org/archive/asiacrypt2007/48330522/48330522.pdf) or some other security notion against CCA2 attacks? –  Nov 23 '12 at 23:59
  • I always thought CCA2 security was (just) the higher of two standard notions of security for public-key encryption. $:$ If one only has bounded-CCA2 non-malleable (www.cs.toronto.edu/~vinodv/boundedCCA.pdf) public-key encryption, then I think something like sign-then-encrypt-then-sign would work best, although I don't know at what stages one would need to include the recipient's name. $:$ (I also notice that the system butchered my previous comment.) $;;$ –  Nov 24 '12 at 01:47
  • 2
    @user991, I've never heard of this "bounded-CCA2 non-malleable" until now; as far as I can tell, it has approximately zero practical relevance. Anyone can invent some crazy security notion, but that doesn't make it relevant. I stand by all of my recommendations and statements in my answer. To be honest, I'm not sure where you're going with your comments. If you have questions, you may want to raise them in a separate question -- I'm not sure if I understand what you are getting at, but they seem to be a bit of a tangent. – D.W. Nov 24 '12 at 02:21
  • The more general statement to make (e.g. from your short answer) is "don't sign anything that doesn't provide enough context" – Tobias Kienzler Sep 11 '13 at 05:36
  • 2
    In your answer and in a comment to another answer to this question you are mentioning prepending the recipient's identity. What effect does it have? What do you mean by recipient's identity? Is it a fixed string, e.g. Bob or is it Bob's public key? – krzychu Nov 07 '16 at 08:55
  • @krzychu, it would typically be Bob's public key (or, in the case of SSL, maybe Bob's domain name)... whatever identity Alice knows Bob by and can check. – D.W. Nov 07 '16 at 14:44
  • 6
    And what effect does it have? As Bob, I receive the message, decrypt it, and then what it gives me, that the message is prepended with my identity? – krzychu Nov 08 '16 at 07:51
  • 1
    @D.W. I also don't understand why to prepend the name before signing. Could you explain why? – M-elman Dec 06 '16 at 17:50
  • 5
    @M-elman I suppose one reason for prepending the name would be that a malicious Bob could pose as Alice by encrypting the exact same message + Alice's signature using Charlie's public key, and trick Charlie into believing that Alice sent him the message. – bkjvbx Feb 28 '17 at 14:40
25

Should we sign-then-encrypt, or encrypt-then-sign? ... Do the same issues with (symmetric-key) MAC-then-encrypt apply to (public-key) sign-then-encrypt?

Yes. From a security engineering standpoint, you are consuming unauthenticated data during decryption if you mac-then-encrypt or sign-then-encrypt. A very relevant paper is Krawczyk's The Order of Encryption and Authentication for Protecting Communications.

The order may (or may not) be problematic in practice for you. But as the SSL/TLS folks have repeatedly shown, its problematic in practice.

Another important paper is cited by D.W. and Sashank: Don Davis' Defective Sign & Encrypt in S/MIME, PKCS#7, MOSS, PEM, PGP, and XML.

I think the primitive of sign vs mac is less important. With all things being equal (like security levels, key management and binding), then one of the top criteria is efficiency. Obviously, a symmetric cipher is more efficient than an asymmetric cipher.


Data authentication is a different property than entity authentication. You can use a MAC for data authentication and a signature for entity authentication.

But its not entirely clear to me if you want data authentication or entity authentication. The security goal you state in (b) begs for data authentication (a MAC), and not entity authentication (a signature).

I think that's why CodesInChaos said he signs then performs authenticated encryption. That's another way to say he signs-then-encrypts-then-macs. If the MAC is good, then he decrypts and verifies the signature to verify who sent the message. If the MAC is bad, then he does not bother decrypting - he just returns FAIL.

If you look at the link provided by Sashank, CodesInChaos' fix is effectively Sign/Encrypt/Sign from Section 5.2 of the paper. And D.W's solution is effectively Naming Repairs from Section 5.1.


There's a third option that's not readily apparent. It combines Encrypt-Then-MAC for bulk encryption with public key cryptography. Its also IND-CCA2 as D.W. suggested you strive for.

The option is an Integrated Encryption Scheme. There are two of them that I am aware. The first is Shoup's ECIES, which operates elliptic curves; the second is Abdalla, Bellare and Rogaway's DLIES, which operates over integers. Crypto++ provides both ECIES and DLIES. Bouncy Castle provides ECIES.

ECIES and DLIES combine a Key Encapsulation Mechanism (KEM) with a Data Encapsulation Mechanism (DEM). The system independently derives a symmetric cipher key and a MAC key from a common secret. Data is first encrypted under a symmetric cipher, and then the cipher text is MAC'd under an authentication scheme. Finally, the common secret is encrypted under the public part of a public/private key pair. The output of the encryption function is the tuple {K,C,T}, where K is the encrypted common secret, C is the ciphertext, and T is the authentication tag.

There's some hand waiving around the use of a symmetric cipher. The schemes use a stream cipher that XORs the plaintext with the output of the KDF. The design choice here was to avoid a block cipher with padding. You could use a block cipher in a streaming mode, like AES/CTR to the same effect.

There is some hand waiving around the "common secret" since its actually the result of applying a Key Agreement function and later digesting the shared secret with a KDF. The Key Agreement function uses the recipient's static public key and an ephemeral key pair. The ephemeral key pair is created by the person doing the encryption. The person performing the decrypt uses their public key to perform the other half of the key exchange to arrive at the "common secret".

The KEM and the DEM avoid padding, so padding oracles are not a concern. That's why a KDF is used to digest the large "common secret" under the KEM. Omitting the padding vastly simplifies the security proofs of the system.

  • 1
    The scheme described on the page you linked to does not provide public key authentication. $\hspace{.91 in}$ –  May 04 '15 at 03:19
  • 1
    @Ricky - the public key cryptography is used in the KEM, not the MAC/Signature. –  May 04 '15 at 03:24
  • 1
    Yes. $:$ Is there public key authentication in that? $;;;;$ –  May 04 '15 at 03:28
  • 1
    @Ricky - the public key cryptography is used in the KEM. Perhaps you should read up on the scheme and then we can talk about it. –  May 04 '15 at 03:32
  • 1
    I might do that when I get back to my computer again, but there's one possibility that occurred to me. $:$ Are you talking about a version in which $R$ is Alice's public key? $:$ (That's not how it's described on the wikipedia page you linked to.) $;;;;$ –  May 04 '15 at 03:39
  • @Ricky - No. The R in an IES is effectively half of a Diffie-Hellman exchange (DH or ECDH); and not a simple key wrap. To arrive at the shared secret, the recipient performs the other half of the key exchange. The shared secret is then digested and used to derive a symmetric cipher key and mac key. To break the scheme, an attacker would need to solve the Diffie-Hellman problem. –  May 04 '15 at 04:02
  • "To break the" scheme's semantic security, "an attacker would need to solve" a hash-Diffie-Hellman problem. $:$ $S_1$ and $S_2$ are "optional shared information", and I don't see what would stop an attacker that knows $S_1$ and $S_2$ from getting Bob to accept arbitrary messages, although I haven't yet read up more on the scheme. $;;;;$ –  May 04 '15 at 04:39
  • @Ricky - Perhaps you should read Shoup's paper and comments on why he insists on adding parameters that others consider optional (here, "others" is like the folks at the IEEE and the P1363 standard). You might also take a look at Crypto++'s implementation, and trace the code surrounding DHAES_MODE. –  May 04 '15 at 04:52
  • With the use of Sign-then-ECIES, it seems that the recipient (let's call it Bob) can still (1) decrypt the ciphertext, (2) re-encrypts towards Charlie. Charlie would receive a correctly encrypted message signed by Alice, while it was not supposed to happen. Is this right or am i missing stg ? – Nikkolasg May 03 '18 at 15:37
  • In the case of data and entity authentication append a device ID, sign, encrypt and calculate MAC using private key only. This is valid to be checked on another client using the public key ? Asymmetric keys are used. – Mohan Radhakrishnan Dec 05 '21 at 13:51
  • Which question are you saying yes to? Are you saying we should encrypt and then sign? – Brōtsyorfuzthrāx Oct 19 '22 at 10:58
  • To me this does not answer the question. In the question it reads "so active attackers can't make Alice think that a message came from Bob when it didn't." If you'd use ECIES then you'd assume a scheme where the only static private key is kept by the receiver and the accompanying public key is trusted by the sender. At the very least some kind of entity authentication must be present to even have data authentication, at the very best without that you can only strive for integrity as anybody can have the public key of the receiver. – Maarten Bodewes Mar 31 '24 at 22:54
17

It depends on your requirement,

  • If you Sign-then-encrypt then only receiver can decrypt and then
    verify .
  • If encrypt-then-sign then anybody can verify the
    authenticity and only receiver can decrypt it .

But in practice, both are not enough , ideally We have to sign-encrypt-sign , am not able to recollect the paper which discusses this

There is one more paper that is popular and discusses this issue in general

sashank
  • 6,174
  • 4
  • 32
  • 67
  • 1
    "If encrypt-then-sign then anybody can verify the authenticity" - Baloney. All that a third party can verify is that there is a signature on some random-looking string, but there's no way to make sense of this (without cooperation from the recipient). This is not a useful capability. In particular, it is not reasonable to call this "verify[ing] the authenticity" of the message. – D.W. Nov 23 '12 at 23:28
  • 10
    "in practice, both are not enough" - False. Sign-then-encrypt is sufficient, if you include the prepend the identity of the recipient before signing. See my answer. (Sign-encrypt-sign is not necessary -- and indeed, in practice no deployed system that I'm familiar with uses sign-encrypt-sign.) – D.W. Nov 23 '12 at 23:30
  • 9
    @D.W , in encrypt-then-sign, If i encrypt with receivers public key and sign with my private key, then anybody knowing my public key ( say some auditor or a proxy agent) can first verify the signature for authenticity ( and drop it if does not match ) but only receiver can actually decrypt it – sashank Nov 24 '12 at 00:44
  • 2
    sashank, in my experience it is very rare for there to be any value in verifying that a signature is valid without being able to verify the contents of the message. (As far as auditing, in my experience any auditor is going to demand to see the contents of the message.) – D.W. Nov 24 '12 at 01:12
  • 8
    @D.W , There is possibility that an attacker could launch denial of service , if the message should be decrypted first in order to verify the signature. The attacker could simply pump in large amounts of garbage and make the decryptor deplete its resources, assuming the message is huge and signature is less in length. – sashank Jul 18 '14 at 00:45
  • 3
    I've recently came across "signcryption" that sign and encrypt in the same time (quicker). – David 天宇 Wong Dec 08 '14 at 14:08
  • @D.W.: Validating the signature can be constant time; which will give you resistance against some classes of timing attacks (i.e. closes off a side channel). While not useful for humans, it can be very useful for machines trying to break other machines. https://en.wikipedia.org/wiki/Timing_attack – Piskvor left the building Feb 04 '16 at 14:29
  • @Piskvor, Everything can be constant time, so that's not quite relevant here as its an implementation detail. Implementors are always free to implement secure protocols insecurely. However, a proper implementation will guard against timing sniffing attacks (and energy sniffing attacks). – Pacerier Oct 24 '17 at 08:29
  • @D.W., How do you address the paper linked in the question then? – Pacerier Oct 24 '17 at 08:32
  • 1
    notice that for "signcryption" - https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6292610/ - "In this paper, an elliptic curve based signcryption scheme for firewalls is analyzed. It is observed that the scheme is not secure and has many security flaws" – Yarix Jun 30 '19 at 17:26
  • Verifying the signature without decrypting a message could be useful for some programs/services (wherein it would be more efficient, and less bother, not to send unauthenticated messages in the first place). – Brōtsyorfuzthrāx Oct 19 '22 at 11:13
  • @sashank That's a bit weird. The only advantage is that you would not need to have any memory for the plaintext, but you'd still have to protect against the message not being to large, right? And then you could just limit memory or use in place decryption. Having two operations instead of 1 is a slight advantage, but that is offset by requiring the additional pass for the signature generation even in normal operation. – Maarten Bodewes Mar 31 '24 at 23:00
1

How about having three different keys: $S_K1, C_K$ and $S_K2$.

  1. $S_K1$ is used to sign the cleartext message.
  2. $C_K$ is used to encrypt the concatenation of the signature generated in (1) and the cleartext.
  3. finally $S_K2$ is used to sign the encrypted output of (2). Then, the message to send is the concatenation of the output of (2) with the output of (3).

I think this is what is done by the milimail extension of Thunderbird.

e-sushi
  • 17,891
  • 12
  • 83
  • 229
daruma
  • 385
  • 3
  • 12
  • 1
    Can you explain why 3 different keys, especially what's the advantage of using two different keys to sign? – not2savvy Jul 09 '19 at 16:22
0

Should we (a) sign-then-encrypt, (b) encrypt-then-sign[, or (c) do something else]?

The answer is: (c), do something else. In specific, it's safest to use authenticated encryption (AE) in encrypt-then-mac mode with associated data (AEAD), as well as to hash the target with associated data (signAD), whether or not the target of the signature is the plaintext (when it's encrypted afterward) or the ciphertext. Both procedures, signAD-then-AEAD and AEAD-then-signAD rely on AEAD, and associated data (AD) generally, to mitigate security issues by committing to contextual values (which can be secret or public) and binding them to jointly achieve authenticated encryption, authentication of associated data, and entity authentication.

Do the same issues with (symmetric-key) MAC-then-encrypt apply to (public-key) sign-then-encrypt?

Yes, both symmetric and asymmetric versions of authenticate-then-encrypt lead to similar security failures. The general problem stems from trusting unverified plaintexts(0). In this mode, since the authentication tag is itself part of the plaintext that it needs to be checking the authenticity and integrity of, it can be toyed with if the ciphertext can be toyed with.

Justification for answer (c):

Even though using AEAD to canonicalize the context of a communication channel (the sender, recipient, time, purpose, transcript summary, etc...) mitigates many of the issues that can arise in hybrid schemes, like surreptitious forwarding of plaintexts & swappable signatures on ciphertexts, it is insufficient. Disambiguating the who's, where's and why's in the authenticated encryption, without also doing so in the hash that's signed, doesn't prevent all forms of these kinds of attacks(1)(2). Let's look at some examples.


sign-then-AEAD:

Bob: $C_{b_0}=$ sign-then-AEAD$($"do you want to get pizza, Alice?"$) \quad\to$ Alice

Alice: $C_{a_0}=$ sign-then-AEAD$($"sure, Bob! let's go at dawn."$) \quad\to$ Eve $\to$ Bob

Bob: $C_{b_1}=$ sign-then-AEAD$($"Alice, do you want to do that dangerous thing?"$) \quad\to$ Alice

Eve: $C_{e_0}=$ $C_{a_0} \quad\to$ Bob

Bob: $C_{b_2}=$ sign-then-AEAD$($"okay, Alice, I trust you. let's do the dangerous thing at dawn."$) \quad\to$ Alice

Consider an $\mathrm{AEAD}_K$ function that includes associated data $A$ and produces a ciphertext $C$ of three concatenated values: the recipient's public key $R_\mathrm{public}$, a plaintext $P$, and the signature $\sigma$ using a sender's identity key $S$ to sign a hash $h_\sigma$ such that:

$$h_\sigma = H(R_\mathrm{public} \space || \space P)$$ $$\sigma = S.\mathrm{sign}(h_\sigma)$$ $$C = \mathrm{AEAD}_K(\sigma \space || \space R_\mathrm{public} \space || \space P, \space A, \space \cdot \space)$$

The goal of $\mathrm{AEAD}_K$ here is to conceal $\sigma$, $R_\mathrm{public}$ and $P$, while binding knowledge of them to $A$, together to be taken as a message sent by an entity that knows the shared secret $K$ and a signature of $P$ by $S$ to $R$. That last part is crucial. Even when we assume good practice, where $A$ and $h_\sigma$ contain acknowledgement of the sender and receiver's public keys, $\sigma$ is free to be passed around after the fact, by anyone, which proves that the holder of $S$ signed the hash of $P$ to $R$, but that could have been for any purpose at any time in the past. $\sigma$ doesn't know anything about the ciphertext it will be embedded within. So, even though the ciphertext may prove linkage to the whole context of the message, the signature does not.

This is clearly inadequate. For one, it allows for replay attacks, as shown by Eve being able to send Bob a ciphertext $C_{a_0}$ they captured from Alice, and trick Bob into thinking it was a legitimate response from Alice to a new question. Thankfully, $\mathrm{AEAD}_K$ could come to the rescue here. If a unique message number is also included within $A$, then $C_{a_0}$ can't be replayed. So, as long as $\sigma$ remains secret, $A$ prevents this surreptitious forwarding of signatures within ciphertexts. However, what's to stop a group of people from communicating using sign-then-AEAD with a common secret in some multi-party protocol? In that case $\sigma$ won't remain secret, and it can directly be injected into unintended contexts, leaving us once again vulnerable. Not to mention that in this example, the plaintext grows with the number of recipients.

Therefore, it would be wise to include as much information within $A$ as possible (even the nonce, the IV, or SIV), to fully and uniquely define a usage context (this message, right now, to x, from y, for this purpose...). $A$ can be passed into the calculation of $h_\sigma$ (signAD) too, so that both the signature and ciphertext cannot be used in an unintended context. As a side note, leaving associated data implicit if possible may be a good idea. It saves on space and communication costs. So, for instance, consider not concatenating recipients to the plaintext. Stuff them into $A$ instead. If you know you know, and if you don't, then you probably don't need to know the details of the channel / message.

keyed-signAD-then-AEAD $(\ref{eq:keyed-signAD-then-AEAD})$:

This example solution is better. It commits to everything and leaks nothing as long as the cipher leaks nothing. A keyed hash is calculated on the data prior to signing. That makes the signatures ephemeral, as well as bound to all the secret and nonsecret values of the channel / message.

\begin{array}{|c|ccc|} \hline \\ \mathrm{\quad \bf{designation} \quad} & & K & S & R & P & \sigma \\ \hline \mathrm{secret} & & \checkmark & \checkmark & \checkmark & \checkmark & \checkmark & \\ \hline \mathrm{nonsecret} & & & & & & & \\ \hline \end{array}

$\label{eq:keyed-signAD-then-AEAD}\tag{$\alpha_0$}$ $$K_E, K_A = \mathrm{KDF}(K, \space \mathrm{canonicalize}(\alpha_0, \space A, \space S_\mathrm{public}, \space R_\mathrm{public}))$$ $$\sigma = S.\mathrm{sign}(H_{K_A}(\mathrm{canonicalize}(P)))$$ $$C = \mathrm{AEAD}_{K_E}(\sigma \space || \space P, \space \cdot \space)$$


AEAD-then-sign:

Bob: $C_{b_0}=$ AEAD-then-sign$($"you never showed up at the dangerous thing, Alice..."$) \quad\to$ Eve $\to$ Alice

Alice: $C_{a_0}=$ AEAD-then-sign$($"sorry, Bob! someone has been following me, so I stayed home."$) \quad\to$ Eve $\to$ Bob

Bob: $C_{b_1}=$ AEAD-then-sign$($"Alice, that's awful. why are they following you?"$) \quad\to$ Eve $\to$ Alice

Alice: $C_{a_1}=$ AEAD-then-sign$($"idk, Bob! maybe they know we're talking to each other?..."$) \quad\to$ Eve $\to$ Bob

Consider a similar set of values such that:

$$_iC = \mathrm{AEAD}_K(P, \space A, \space \cdot \space)$$ $$h_\sigma = H(R_\mathrm{public} \space || \space _iC)$$ $$\sigma = S.\mathrm{sign}(h_\sigma)$$ $$C = \sigma \space || \space _iC$$

The goal of $\mathrm{AEAD}_K$ here is to conceal $P$, while binding knowledge of it to $\sigma$, $R_\mathrm{public}$ and $A$, together to be taken as a message sent by an entity that knows the shared secret $K$ and the signature of $C$ by $S$ to $R$. In this scenario, $\sigma$ is bound to $C$, which is good in the sense that $C$ encapsulates all of the contextual data of the message. But, it's not so good in that anyone can strip off the signature and replace it with their own. $\mathrm{AEAD}_K$ prevents this by adding $S_\mathrm{public}$ and $R_\mathrm{public}$ to $A$, which means the recipient will get a failure-to-decrypt message ($\bot$) if the wrong signing key is used to make $\sigma$.

But there's another big problem. Alice realizes that he is being followed, and hints that it may be because of his communications with Bob. Maybe this is just paranoia on Alice's part, but AEAD-then-sign can enable this kind of tracking. How? Well, first Eve gets hold of a ciphertext $C$ from listening in on either Alice or Bob. Then Eve tests some known directory of public keys to find a pair which satisfies

$$S'.\mathrm{verify}(\sigma, \space H(R'_\mathrm{public} \space || \space _iC))$$

This is an issue which stuffing more public values into $A$ or $h_\sigma$ would not solve. It would be understandable to consider if such a structure is even valuable when it can be so detrimental to privacy. Though, there are some documented use cases in the area of publicly verifiable ciphertexts. In which case, it may be appropriate to remove $R_\mathrm{public}$ from the calculation of $h_\sigma$, so the signature can be verified without knowing the recipients. If the verifier isn't fully public, say it's some semi-trusted service, it may also be appropriate to add a secret value, or use a keyed-hash, when calculating $h_\sigma$. That way only entities who are given the secret value will have permission to verify recipients.

AEAD-then-keyed-signAD-1way $(\ref{eq:AEAD-then-keyed-signAD-1way})$:

This example solution enables an entity outside of the communication channel to verify that a ciphertext has been issued by a signing party using an ephemeral key $K_A$. The outside entity doesn't learn anything about the recipient's identity information since $K_A$ is ephemeral.

\begin{array}{|c|ccc|} \hline \\ \mathrm{\quad \bf{designation} \quad} & & K & S & R & P & \sigma & \\ \hline \mathrm{secret} & & \checkmark & & \checkmark & \checkmark \\ \hline \mathrm{nonsecret} & & & \dagger & & & \dagger \\ \hline \end{array}

$\label{eq:AEAD-then-keyed-signAD-1way}\tag{$\alpha_1$}$ $$K_E, K_A = \mathrm{KDF}(K, \space \mathrm{canonicalize}(\alpha_1, \space A, \space S_\mathrm{public}, \space R_\mathrm{public}))$$ $$C = \mathrm{AEAD}_{K_E}(P, \space \cdot \space)$$ $$\sigma = S.\mathrm{sign}(H_{K_A}(\mathrm{canonicalize}(S_\mathrm{public}, \space C)))$$

AEAD-then-keyed-signAD-2way $(\ref{eq:AEAD-then-keyed-signAD-2way})$:

This example solution enables an entity outside of the communication channel to verify that a ciphertext has been issued by a signing party to specific recipients, using an ephemeral key $K_A$.

\begin{array}{|c|ccc|} \hline \\ \mathrm{\quad \bf{designation} \quad} & & K & S & R & P & \sigma & \\ \hline \mathrm{secret} & & \checkmark & & & \checkmark \\ \hline \mathrm{nonsecret} & & & \dagger & \dagger & & \dagger \\ \hline \end{array}

$\label{eq:AEAD-then-keyed-signAD-2way}\tag{$\alpha_2$}$ $$K_E, K_A = \mathrm{KDF}(K, \space \mathrm{canonicalize}(\alpha_2, \space A, \space S_\mathrm{public}, \space R_\mathrm{public}))$$ $$C = \mathrm{AEAD}_{K_E}(P, \space \cdot \space)$$ $$\sigma = S.\mathrm{sign}(H_{K_A}(\mathrm{canonicalize}(S_\mathrm{public}, \space R_\mathrm{public}, \space C)))$$


Conclusion:

The main takeaways, which are supported in recent works and in the design of modern libraries, are that key material, signatures, and hashes, should unambiguously commit to specific and unique usage contexts. Doing so with care can make both the safest options (signAD-then-AEAD) and the riskier options (AEAD-then-signAD) safer.

aiootp
  • 773
  • 2
  • 8
  • If you already have a shared secret key then you can just encrypt-then-mac, right? At least some reference should be made about the required key management. – Maarten Bodewes Mar 31 '24 at 23:03
-1

For Authenticated Encryption, the best practice is "encrypt and then MAC". Encrypt and then MAC is always AE secure (assuming the encryption is CPA secure and the MAC is secure), but MAC then Encrypt is not always secure. The NIST AES-GCM AEAD scheme is based on "Encrypt then MAC". The SSL padding attack exploits the fact that its AE is based on "MAC and then Encrypt". Also, when you "MAC and then Encrypt" you operate encryption on a data that its entropy is decreased, due to the addition of the MAC, that is dependent on the data, and does not add entropy. So, for AEAD it is better to use encrypt and then MAC. Nevertheless, you are asking about digital signature, and intuitively I think that the same practice should be used (i.e. Encrypt and then sign), although I did not find a security prove.

Evgeni Vaknin
  • 1,076
  • 7
  • 18
-4

The only difference between these approaches has to do with hiding information about the sender. If you don't want attackers to know who the signer is, you need to sign-then-encrypt. In other cases it doesn't matter.

Patriot
  • 3,132
  • 3
  • 18
  • 65
Pavel Ognev
  • 147
  • 4
  • There might be a successful chosen ciphertext attack against sign-then-encrypt. $\hspace{1.4 in}$ –  Nov 23 '12 at 08:02
  • @Ricky Demer: How can attacker get a plain text? There are no conditions for chosen ciphertext model. – Pavel Ognev Nov 23 '12 at 08:31
  • For example, it might be easy to come up with a ciphertext whose decryption is the result $\hspace{1 in}$ of setting the $n$th bit in the original plaintext to zero. $:$ –  Nov 23 '12 at 08:38
  • If attacker change the ciphertext somehow, the decrypted text will be changed too and signature verification will fail. – Pavel Ognev Nov 23 '12 at 10:57
  • Not necessarily. $:$ For semantic security to hold, there must be different $\hspace{1.6 in}$ ciphertexts that decrypt to the same plaintext. $;;$ –  Nov 23 '12 at 11:25
  • So, what is the problem in this case? If recipient get a correct plaintext, no matter how it was derived. – Pavel Ognev Nov 23 '12 at 11:47
  • @PavelOgnev For example if you sign first and then encrypt with AES-CBC, you're still open to padding oracles. And a malleable ciphertext with fixed plaintext can be a problem in some contexts. – CodesInChaos Nov 23 '12 at 12:27
  • Ok, I'll ask another way: what property of transferred information can be broken? Confidence, integrity, authenticity or what else? – Pavel Ognev Nov 23 '12 at 13:02
  • If the encryption is CBC, then you can probably use a padding oracle to decrypt the message, breaking confidentiality. – CodesInChaos Nov 23 '12 at 13:33
  • Ok, now I finally understood what did you mean. No, recipient is not a padding oracle. he just says "Signature is correct" or "Error". No information of correct or incorrect decryption. Even if attacker can modify ciphertext to be decrypted to the same plaintext, he cannot get any block of this plaintext. – Pavel Ognev Nov 23 '12 at 15:20
  • The point is that an attacker might be able to learn the plaintext from what $\hspace{1.8 in}$ ciphertexts give "Signature is correct". $:$ –  Nov 23 '12 at 20:59
  • 5
    @RickyDemer, regarding your comment "There might be a successful chosen ciphertext attack against sign-then-encrypt." - Not if you use a IND-CCA2-secure encryption scheme and a UF-CMA-secure signature scheme, and if you prepend the recipient's identity first. See my answer. (In general, the quality of technical analysis in this comment thread is low, and many comments seem to lack familiarity with the relevant technical literature, so I would caution by-standers to take what you read with a grain of salt.) – D.W. Nov 23 '12 at 23:32
  • 1
    @Ricky Demer: signature will be correct only if all decrypted text including padding is identical to the sender's source. So, attacker will take message "Signature is correct" in 2 cases: 1) he pass the message unchanged. 2) He changes ciphertext in some way so the decrypted text is the same as in correct message. The only way to do that is re-encrypting entire message with different IV. I don't think it's possible without knowing the key. – Pavel Ognev Nov 24 '12 at 21:27