Search code examples
javaencryptiondigital-signaturebouncycastlepgp

How To verify Ascii-Armored data after decryption in PGP using Bouncy Castle?


I'm relatively new to PGP and bouncy castle. After signing a message, get a ascii-armored data back. Let's assume this ascii-armored data is encrypted and decrypted and waiting for sign verification. Here are my following doubts:

  1. Does the Ascii-armored data that I receive contains the signed data ready for encryption or just the sign digest? (as per the code for signing provided)

  2. If it contains the complete signed data, How do I extract data and sign from within the Ascii-armored data and use them for verification?

  3. If not should i append the sign to the raw data manually and how to do so ?

Code For Reference

    private ByteArrayOutputStream signData(byte[] data, PGPPrivateKey privateKey, int hashAlgo) throws PGPException, IOException {
        JcaPGPContentSignerBuilder contentSignerBuilder = new JcaPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, hashAlgo)
                .setProvider(BouncyCastleProvider.PROVIDER_NAME);
        PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
                contentSignerBuilder
        );
        signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ArmoredOutputStream armoredOut = new ArmoredOutputStream(byteOut);
        BCPGOutputStream bOut = new BCPGOutputStream(armoredOut);

        signatureGenerator.generateOnePassVersion(false).encode(bOut);
        signatureGenerator.update(data);
        signatureGenerator.generate().encode(bOut);

       armoredOut.close();
        return byteOut;
    }

Sample Ascii-armored Data:

-----BEGIN PGP MESSAGE-----
Version: BCPG v1.77.00

kA0DAAgBASaMeyE5SE4BiJwEAAEIAAYFAmZdbXMACgkQASaMeyE5SE4nMQP/Rc0C
3U2wD4htYYwln7yOTScpVY0p6gWeIx/u5ai/kOAE1fdHN8HAAA+X3LoeSMzqv76C
F+yGcWmKH363xM5pcuvk3kGZ8F0gDlfuAJMlfvUjRdDC4FrvB5uoScBYQPz2w3Wr
wGCZl40tEXo7tvUja9SLKmhHviXS5FpPaXGJ2Xc=
=ozi9
-----END PGP MESSAGE-----

Kindly, let me know if there is any other ideal way of doing signing and verification without ascii-armored data or so.

Also I don't understand a lot of OnePassSignatureList verification, kindly provide me a code sample and explain how it works.


Solution

  • " Let's assume this ascii-armored data is encrypted and decrypted and waiting for sign verification."

    Why would you assume encryption / decryption? ASCII armor is about encoding / decoding.

    Does the Ascii-armored data that I receive contains the signed data ready for encryption or just the sign digest? (as per the code for signing provided)

    The data that has been signed is not included in the container. If it should be then it should be included in a packet containing literal data.

    What do you mean with "ready for encryption"? Signature generation is not encryption and any data can be encrypted.

    If it contains the complete signed data, How do I extract data and sign from within the Ascii-armored data and use them for verification?

    "sign" -> "signature", that kind of messy writeup will introduce misunderstandings. You can use a PGPSignatureVerifier and the PGPSignatureVerifierBuilder.

    If not should i append the sign to the raw data manually and how to do so ?

    Perform the following before the update:

    PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
    try (OutputStream literalOut = literalDataGenerator.open(bOut, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, data.length, new Date())) {
        literalOut.write(data);
    }
    

    Kindly, let me know if there is any other ideal way of doing signing and verification without ascii-armored data or so.

    Seriously? Remove the ArmoredOutputStream...

    Also I don't understand a lot of OnePassSignatureList verification, kindly provide me a code sample and explain how it works.

    No. If you're that lazy use an AI for an example. Or ask a concise question about it. "Explain how it works" is generally too broad.