Search code examples
c#encryptionbouncycastleopenpgp

PGP BouncyCastle + Kleopatra Decryption: Unknown Packet Type: 20


I am attempting to decrypt a file using BouncyCastle in C# that has been encrypted with RSA via Kleopatra. Unfortunately, I am receiving an error that states "Unknown packet type encountered: 20" when processing through the first few lines of decryption. The (pseudo) code:

   using (Stream inputStream = File.OpenRead(test.txt.gpg))
   {
       using (Stream keyIn = File.OpenRead(privatekey.asc))
       {
                PgpObject o = null;

                PgpObjectFactory pgpF = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
                
                PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

                if (pgpF != null)
                {
                    o = pgpF.NextPgpObject(); -- THIS LINE THROWS THE UNKNOWN PACKET TYPE ERROR
                }
       }
   }

After googling, I have seen examples that the above code snippet models, but I have not yet seen any information about unknown packet types.

Does anyone know if I am doing anything wrong, or can point me in the direction of documentation of the error code numbers?

Thank you in advance for your time.


Solution

  • This packet type is not part of the official OpenPGP standard as defined in RFC 4880, which defines packet types only up to 19 (see section 4.3).

    However, there is a Work in progress to update the OpenPGP specification from RFC4880 which defines packet type 20 as AEAD Encrypted Data Packet (see section 5.16).

    AEAD means Authenticated Encryption with Associated Data. It allows to include data from outside the actual encryption data in the authentication part. This aims at making it impossible to use the encrypted data outside its original context, effectively disabling a replay attack. For details, see this answer.

    Obviously, said draft has not been approved (yet?), but also has expired. I'm unsure about what exactly this means. Nevertheless, GnuPG seems to have implemented the proposal in its new version 2.3 (which Kleopatra uses under the hood), and even made it default, as I understand the docs (quoted from OpenPGP protocol specific options):

    The MDC is always used unless the keys indicate that an AEAD algorithm can be used in which case AEAD is used.

    By default, GnuPG 2.3+ generates keys that support AEAD, and when a key claims support for AEAD, GnuPG will use it to encrypt data.

    BouncyCastle does not currently support PGP encryption with AEAD. As a work-around for this problem, PGP keys should be generated using GnuPG with the --rfc4880 or --openpgp flag which makes sure that the key adheres to RFC 4880.

    It's also possible to remove AEAD from an existing key. To do so, first, edit the key and display the existing options:

    $ gpg --expert --edit-key <FINGERPRINT>
    gpg> showpref
    [ultimate] (1). Foobar McFooface (test) <[email protected]>
        Cipher: AES256, AES192, AES, 3DES
        AEAD: OCB
        Digest: SHA512, SHA384, SHA256, SHA224, SHA1
        Compression: ZLIB, BZIP2, ZIP, Uncompressed
        Features: MDC, AEAD, Keyserver no-modify
    

    Then set the same options without AEAD:

    gpg> setpref AES256 AES192 AES SHA512 SHA384 SHA256 SHA224 ZLIB BZIP2 ZIP
    Set preference list to:
        Cipher: AES256, AES192, AES, 3DES
        AEAD:
        Digest: SHA512, SHA384, SHA256, SHA224, SHA1
        Compression: ZLIB, BZIP2, ZIP, Uncompressed
        Features: MDC, Keyserver no-modify
    Really update the preferences? (y/N) y
    

    (Found on GnuPG ArchWiki: 8.1 Disable unsupported AEAD mechanism)


    Updates

    In version 1.72 of BouncyCastle (Java library), support for PGP with AEAD has been added.

    There's an upcoming OpenPGP Standard Refresh that includes AEAD.