I read a book called "computer networking: A top-down approach". It talked about how PGP creates an email message between Alice and Bob to maintain confidentiality, integrity, and authenticity. Let me define some terminology and the procedure at the very high level:

m :              email message
H() :            cryptographic hash function
Ka_priv_sign() : signing using Alice's private key
|| :             contacternation
Ks :             session key
Ks_enc():        encryption using session key
Kb_pub_enc():    encryption using bob's public key
blob :           The final data blob Alice sends to Bob.

To send an email to Bob, Alice first signs the message with her private key:

m || Ka_priv_sign(H(m))

Alice then encrypt the message and signature

blob = Kb_pub_enc(Ks) || Ks_enc(m || Ka_priv_sign(H(m))) 

Alice will send this final blob to Bob.

The cryptography seems to have a problem here since digital signature is applied before encryption and encryption does not provide data integrity. I think the right order of operation should be:

Alice first encrypts the message with the session key and encrypt the session key with Bob's public key:

Kb_pub_enc(Ks) || Ks_enc(m)

Alice then signs the encryption results after hashing them:

blob' = Kb_pub_enc(Ks) || Ks_enc(m) || Ka_priv_sign(H(Kb_pub_enc(Ks) || Ks_enc(m)))) 


Is PGP still using the way that the textbook describes today? Do you think my construction is better?


As fgrieu noted in his answer using sign-then-encrypt is probably the best way of handling encrypted & signed messages.

However when the OpenPGP format in RFC 4880 is studied it seems that it uses both PKCS#1 v1.5 padding and CBC mode encryption. Both schemes are vulnerable to padding oracle attacks.

So it is important to make sure the software is not vulnerable against padding oracle attacks. One way to do that would be by only decrypting it on a per message bases or by using it for in place encryption/signing. Another method is making sure that the implementation of PGP is not vulnerable to padding oracle attacks.

I would not call this "optimal" - more modern schemes should be used for encrypting the message and the wrapped symmetric key.

So basically sign-then-encrypt is OK, but the schemes used for encryption aren't.

  • $\begingroup$ Probably you could use sign-then-encrypt-then-sign, but I haven't seen many references to that scheme. Disadvantage is obviously another pass and another use of the private key for signature generation. Maybe we need a scheme that performs signing and encryption in one go (that could be tricky because of the different schemes and key sizes for signing and encryption keys). $\endgroup$ – Maarten Bodewes Jun 13 '16 at 9:02
  • $\begingroup$ PGP uses tweaked CFB, not CBC; the tweak includes some early redunancy which can be checked and if so can similarly give an oracle, but this check isn't necessary the way CBC block unpadding is. $\endgroup$ – dave_thompson_085 Jun 14 '16 at 3:30

Yes, PGP's sketch as in the question is sound by today's textbooks on cryptography, and reasonable from a computer security standpoint. Applying digital signature then encryption (critically: including on the signature) does provide data integrity and confidentiality for the message.

PGP's way of doing things has the characteristic that one able to decipher the message can turn it into a cleartext message signed by Alice, that anyone (knowing and trusting Alice's public key) can verify. In many cases, that's a feature.

It can occasionally become a weakness when PGP is misused. Assume Alice sends a message to Mallory like "I love you", signed by Alice, encrypted to Mallory; Mallory can decipher the message, and forward it to Bob, still signed by Alice, perhaps even re-encrypted to Bob; Bob, if he does not understand what PGP signature really means, can be tricked into thinking Alice cares for him. That's also Alice's fault: she should have signed a more context-free message, like "I love you Mallory" (and be more selective). More examples here (which takes the debatable position this is a defect in PGP).

There's also the argument, legitimately made by some computer security material, that with sign-then-encrypt as in PGP, the receiver deciphers something unauthenticated, and that can allow exploitation of software bugs in the decryption, or after. In the context of PGP, that argument does not hold: PGP is designed to support unauthenticated enciphered messages; and one legitimately wants to be able to read messages that one is not able to authenticate, for lack of the alleged signer's trusted public key.

Update: this answer is only about the soundness of the overall structure of the PGP format as described in the question; I do not touch "optimality", for lack of a definition; nor try to examine the detailed PGP formats and implementations (which are not state of the art), as discussed in that other answer.


and encryption does not provide data integrity.

You might want to read up on authenticated encryption. However, even if that isn't used it's still not a big problem for if an attacker corrupts the encrypted text the cleartext produced the by corrupted ciphertext cannot be authenticated, i.e. the signature will be corrupted or the hashes won't be equal.


Not the answer you're looking for? Browse other questions tagged or ask your own question.