简体   繁体   中英

How do I create an ascii-armored signed OpenPGP message using ArmoredOutputStream of the BouncyCastle crypto library (C# version)

When I use ArmoredOutputStream I get a "-----BEGIN PGP MESSAGE-----" instead of a "-----BEGIN PGP SIGNATURE-----" after the clear text. I cannot figure out how to use ArmoredOutputStream on my own. Sometimes I get the signature header, but have non-base64 characters in the message. The BC legionaries must be sadists releasing such a good library with nearly no documentation how to use it...

Here is my code:

    private void doTestSig(
        PublicKeyAlgorithmTag encAlgorithm,
        HashAlgorithmTag hashAlgorithm,
        PgpPublicKey pubKey,
        PgpPrivateKey privKey)
    {
        MemoryStream testIn = new MemoryStream(TEST_DATA, false);
        MemoryStream baseOut = new MemoryStream();

        ArmoredOutputStream aOut = new ArmoredOutputStream(baseOut);
        aOut.BeginClearText(hashAlgorithm);
        aOut.Write(testIn.ToArray(), 0, testIn.ToArray().Length);
        aOut.EndClearText();

        PgpSignatureGenerator sGen = new PgpSignatureGenerator(encAlgorithm, hashAlgorithm);
        sGen.InitSign(PgpSignature.BinaryDocument, privKey);
        sGen.GenerateOnePassVersion(false).Encode(aOut);


        PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
        Stream lOut = lGen.Open(
            new FilterStream(aOut),
            PgpLiteralData.Binary,
            PgpLiteralDataGenerator.Console,
            TEST_DATA.Length * 2,
            DateTime.UtcNow);

        int ch;
        while ((ch = testIn.ReadByte()) >= 0)
        {
            aOut.WriteByte((byte)ch);
            sGen.Update((byte)ch);
        }        

        lOut.Write(TEST_DATA, 0, TEST_DATA.Length);
        sGen.Update(TEST_DATA);

        lGen.Close();

        sGen.Generate().Encode(aOut);

        aOut.Close();

        byte[] outarr = baseOut.ToArray();
        string strOut = System.Text.Encoding.UTF8.GetString(outarr, 0, outarr.Length);
// strOut gets this:
// "-----BEGIN PGP SIGNED MESSAGE-----\r\n
// Hash: SHA1\r\n
// \r\n
// hello world!\n
// hello world!\n
// 
// -----BEGIN PGP MESSAGE-----\r\n
// Version: BCPG C# v1.7.0.0
// \r\n
// \r\n
// kA0DAAIR4GIXExqVFDEBy0JiCF9DT05TT0xFVBcoRmhlbGxvIHdvcmxkIQpoZWxs\r\n
// byB3b3JsZCEKaGVsbG8gd29ybGQhCmhlbGxvIHdvcmxkIQqIRgQAEQIABgUCVBco\r\n
// RgAKCRDgYhcTGpUUMXglAJwNOiEzA7H9RxaoU/gs9AoxZCOd+ACffl8lJ/6ZNpkB\r\n
// FLBjbd9wlEU3/SY=\r\n=u7Mk\r\n
// -----END PGP MESSAGE-----\r\n"

    }

Finally I found a source code that demonstrates the use of ArmoredOutputStream:

        // Setup signature stuff
        var signatureData = new PgpSignatureGenerator(encAlgorithm, hashAlgorithm);
        signatureData.InitSign(PgpSignature.CanonicalTextDocument, privKey);

        foreach (string userId in pubKey.GetUserIds())
        {
            var subPacketGenerator = new PgpSignatureSubpacketGenerator();

            subPacketGenerator.SetSignerUserId(false, userId);
            signatureData.SetHashedSubpackets(subPacketGenerator.Generate());

            // Just the first one!
            break;
        }

        using (var sout = new MemoryStream())
        {
            using (var armoredOut = new ArmoredOutputStream(sout))
            {
                armoredOut.BeginClearText(hashAlgorithm);

                using (MemoryStream testIn = new MemoryStream(TEST_DATA, false))
                {
                    int ch;
                    while ((ch = testIn.ReadByte()) >= 0)
                    {
                        armoredOut.WriteByte((byte)ch);
                        signatureData.Update((byte)ch);
                    }     
                }

                armoredOut.EndClearText();

                using (var outputStream = new BcpgOutputStream(armoredOut))
                {

                    signatureData.Generate().Encode(outputStream);
                }

                byte[] outarr = sout.ToArray();
                string strOut = System.Text.Encoding.UTF8.GetString(outarr, 0, outarr.Length);

Note that this code doesn't include a fix for the missing linebreak before '-----BEGIN PGP SIGNATURE-----' bug in the library. You have to add it yourself in the output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM