I’ve already read the discussion Should we sign-then-encrypt, or encrypt-then-sign? and the paper Defective Sign & Encrypt in S/MIME, PKCS#7, MOSS, PEM, PGP, and XML. My question has to do with what gpg is doing. This has been a bit difficult to discern empirically, since the output of:

gpg --encrypt --sign <filename>

Changes each time I run it. (Why?)

@Jens has explained that part of the reason is that a timestamp is included. Is there any way to eliminate that? I’m not seeing a gpg option.

As the order of options presumably makes no difference, and since I can’t use the --detach-sign option (only a single file of output is produced, regardless), I am suspecting that the output represents:

E_r (msg\  \| \ E_s (\#msg))

where $E_r$ is encryption with the recipient’s public key, $E_s$ is encryption with the sender's private key, $msg$ is the message, $\#msg$ is the hash of the message and $\|$ is concatenation. ie. this would be “sign-the-message-then-encrypt.” Is this correct?

Or is it instead:

E_r (msg) \  \| \ E_s (\#msg)

In other words, is it “encrypt-then-sign-using-the-plain-text?” I am assuming it is not “encrypt-then-sign-the-cyphertext” ($E_r (msg) \ \| \ E_s (\# E_r (msg))$) as that would be counter to Section 1.2 in the paper mentioned above.

@Jens has explained that it is indeed “sign-the-message-then-encrypt.” So how would we “encrypt-then-sign-using-the-plain-text,” with the output a single openpgp file, rather than two files, one the encrypted data and the other the signature?

Also, I’ve read the papers & I’ve read the manuals - where, other than the code itself, would I go to look this up?

@Jens suggested running:

echo 'foo' | gpg --recipient [key-id] --encrypt --sign | gpg --list-packets 

I ran it, encrypting to myself and found the output below. Could someone elucidate what it's telling us?

gpg: okay, we are the anonymous recipient.
:encrypted data packet:
    length: unknown
    mdc_method: 2
gpg: encrypted with RSA key, ID 00000000
:compressed packet: algo=2
:onepass_sig packet: keyid C6701618143AFA1E
    version 3, sigclass 0x00, digest 10, pubkey 1, last=1
:literal data packet:
    mode b (62), created 1443494042, name="",
    raw data: 4 bytes
:signature packet: algo 1, keyid C6701618143AFA1E
    version 4, created 1443494042, md5len 0, sigclass 0x00
    digest algo 10, begin of digest d7 3a
    hashed subpkt 2 len 4 (sig created 2015-09-29)
    subpkt 16 len 8 (issuer key ID C6701618143AFA1E)
    data: [4095 bits]
  • I'm still interested in the answers to the (embedded) questions.
    – Diagon
    Jun 12, 2016 at 4:12
  • 1
    For those coming after, the following is an interesting exploration of the output of --list-packets: davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key
    – ptim
    Sep 1, 2020 at 23:50
  • @ptim Excellent, thanks. I've also created a couple of question/answers that are relevant to the nature of trust, the various types of signatures, and the distinction between "signing" and "certifying"
    – Diagon
    Sep 2, 2020 at 4:32

1 Answer 1


This has been a bit difficult to discern empirically, since the output of:

gpg --encrypt --sign <filename>

changes each time I run it. (Why?)

This has two reasons:

  1. The symmetric encryption in OpenPGP makes use of a random initialization vector (or rather, a similar construct with a fixed initialization vector)
  2. The signature creation timestamp is included.

Sign & Encrypt vs. Encrypt & Sign - What does gpg do?

GnuPG first signs a message, then encrypts it. You can verify this using gpg --list-packets:

echo 'foo' | gpg --recipient [key-id] --encrypt --sign | gpg --list-packets

Which first signs and then encrypts a message, as the order of the packets indicates.

From my understanding of RFC 4880, OpenPGP, both orders are defined, though: OpenPGP messages can be signatures, encrypted, compressed and literal data, while signatures are applied on OpenPGP messages, and decrypted messages must also form OpenPGP messages.

  • Added command output and request for clarification into the (so far very helpful) answer.
    – Diagon
    Sep 27, 2015 at 22:16
  • @Diagon: your edit was rejected, as edits in answers are not meant to be used for requests in clarification. Use comments instead, or edit the original question (and be sure to stay within the scope of the original question, otherwise ask a new one).
    – Jens Erat
    Sep 28, 2015 at 13:08
  • Ok, I edited the question. It doesn't appear possible to include in comments the formatted output that I was trying to post, thus my prior jerry-rigged solution. Also, my question directly relates to the crypto.stackexchange.com question in the first link in my (present) question. Thus, I don't think superuser is really the right place. Furthermore, there doesn't appear to be Latex here, so my question is now kind of fubar.
    – Diagon
    Sep 29, 2015 at 2:50
  • @JensErat Could you please tell where in the RFC it is explained that encrypt & sign is allowed? Would be great! Unfortunatley, I am unable to find it.
    – efie
    Mar 5, 2017 at 22:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .