如何使用BouncyCastle加密库(C#版本)的ArmoredOutputStream创建ascii铠装签名Open

本文关键字:ascii 创建 ArmoredOutputStream Open 加密 BouncyCastle 何使用 版本 | 更新日期: 2023-09-27 18:22:00

当我使用ArmoredOutputStream时,我会在明文后得到一个"-----BEGIN PGP MESSAGE------",而不是"-----BEGIN PGP SIGNATURE------"。我不知道如何单独使用ArmoredOutputStream。有时我得到签名头,但消息中有非base64字符。不列颠哥伦比亚省的军团一定是虐待狂,他们发布了一个几乎没有文件说明如何使用它的好图书馆…

这是我的代码:

    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"
    }

如何使用BouncyCastle加密库(C#版本)的ArmoredOutputStream创建ascii铠装签名Open

最后我找到了一个演示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);

请注意,此代码不包括对库中"-----BEGIN PGP SIGNATURE------"错误之前缺少换行符的修复。您必须自己将其添加到输出中。