如何使用 Bouncy Castle 或其他 C# 库在 C# 中验证此 PGP 消息

发布于 2024-11-19 10:09:09 字数 745 浏览 3 评论 0原文

我需要做的就是验证下面的消息,但我无法让 Bouncy Castle 接收数据并给出公钥验证消息。如果它是免费的,我很高兴它成为其他可以使用的库。这将嵌入到我的通过互联网接收数据的应用程序中,因此如果可能的话,我宁愿保留所有托管代码。

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SCI Version: 1.0
SCI Code: 1
SCI Reason: OK
SCI Balance: 0.00050000

-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MBC v1.0

iQEcBAEBAgAGBQJOGSuYAAoJEJ+5g06lAnqFkdsH/0NoqQbNvR8ZPe8D4gL4gvff
6K1t2LOt0sQGj+RSPeEbag7ZnVNI65LiES/yie1N6cXMkFgb9/ttjxi9/wlbxD/j
gSkuZ6mT9Oc5ExLsRZq9ygytvVs7Ol7uQm6oxDzJX1JMs0ls2EwJbmmpTEOHn8Av
dGlxdZeh+3RlqHJmOdssQCJ0cw5VXuj5vfP35OYz2zO2+sNg0eCXdR5Ml+2S7n3U
n9VHPEECg72LvpxF/y/nApopXoHpwECXoBwHgyd9QIIw1IJgalyRLDmAJ2WXdROV
ln2Mkt/km3KtBS3h4QL407wi/KhgZ4tFohZupt7zq2zUwtHWOhbL2KSUu939OKk=
=mIjM
-----END PGP SIGNATURE-----

All i need to do is verify the message below but I can not get Bouncy Castle to take the data in and given the public key verify the message. I am happy for it to be some other Lib that is used if it is free. This is to be embedded in my app that receives data over the Internet so i would prefer to keep it all managed code if at all possible.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SCI Version: 1.0
SCI Code: 1
SCI Reason: OK
SCI Balance: 0.00050000

-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MBC v1.0

iQEcBAEBAgAGBQJOGSuYAAoJEJ+5g06lAnqFkdsH/0NoqQbNvR8ZPe8D4gL4gvff
6K1t2LOt0sQGj+RSPeEbag7ZnVNI65LiES/yie1N6cXMkFgb9/ttjxi9/wlbxD/j
gSkuZ6mT9Oc5ExLsRZq9ygytvVs7Ol7uQm6oxDzJX1JMs0ls2EwJbmmpTEOHn8Av
dGlxdZeh+3RlqHJmOdssQCJ0cw5VXuj5vfP35OYz2zO2+sNg0eCXdR5Ml+2S7n3U
n9VHPEECg72LvpxF/y/nApopXoHpwECXoBwHgyd9QIIw1IJgalyRLDmAJ2WXdROV
ln2Mkt/km3KtBS3h4QL407wi/KhgZ4tFohZupt7zq2zUwtHWOhbL2KSUu939OKk=
=mIjM
-----END PGP SIGNATURE-----

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不乱于心 2024-11-26 10:09:09

对于那些感兴趣的人,我在 BouncyCastle 源代码中发现了这个确切任务的示例。您需要下载源代码而不是二进制文件才能获取示例,并且似乎有针对所有不同 OpenPGP 用例的示例。

For those interested i discovered an example for this exact task in the BouncyCastle source code. You need to download the source code not the binary to get the examples and it seems to have examples for all the different OpenPGP use cases.

你是年少的欢喜 2024-11-26 10:09:09

按照 Seer 的建议查看 这个例子我终于运行了消息验证。

我有方法 VerifyFile ,它接受签名消息和公钥,并在验证通过时返回消息内容。例如,它可以这样使用:

string key = @"-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG C# v1.6.1.0

mQENBFpc87wBCACK5FG6Z70iovzSzQF7OEB/YbKF7SPS1/GZAQhp/2n2G8x5Lxj5
/CKqR8JLj1+222unuWgfqvfny0fLvttt1r6lAH/kqDYMBg26GTbZy93R5BYatBjd
pzYl/lIyKxc/QwDdZm8zNxeUpDSfoe9jVULOg0MiMDtdQupOf6CanlEioXfyf88F
1BLcJyFSckaYieosBw5hnnI+1cZZ3k+4HpDJJslVzngfTPWRibtN5PKff1CKP55E
ME99XkuPDaNL7XZmu7lZSEUN3jJFVydZQrDkvxddihzV4pTgRI3gDAFoJxxIYZX3
JsQAJItlqq8bBsQ+bKPikgAiMySGcEi+ilI5ABEBAAG0GnNoYWxhbWFub3YubWFy
aW5AZ21haWwuY29tiQEcBBABAgAGBQJaXPO8AAoJEBvHdfmVFHzkvHEH/179VAdH
gWRN5HVprsp4vHP3q1CJV9j+fPlQIZU3JEwrM+INxzpfSqZeN4NwB7yoo2NCdCNP
Ndg8zhiuEYM51hNtqU5cwYBcaAbm1so6TSVo8i4nrfN3+oDYEfYPqglNrd1V233J
oyLriwpGkR6RBYMY2q2Re+EFNR1bxUmeE0wnb8FOodRCSh0Wd3Iy9mvmhv5voHIr
aZzgsuifGw1JilSu9+RoC6b1CHb9jUkWQ/odkTvl5/rxA14TKstgoLoSLHktYQfw
le6B8+lPtmODtagWoDEeR/M0zm/wyCOt5wqjjJCgvaipUaA+oiijIYwCpqUBwfm3
DZ9DStGHGVxQQnc=
=s91O
-----END PGP PUBLIC KEY BLOCK-----
";
string message = @"-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test tes tes ts tse tse t
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v1.0.1
Comment: http://openpgpjs.org

wsBcBAEBCAAQBQJaXP5WCRAbx3X5lRR85AAAUcoH/jtcyWcpTVyXyz/ptWLo
Hx+g51EeeA0Hpq7kZCXu4FuyhNn/QvnvKyt9qegxQoRSZhT37ln8t80NW6sS
B4XVFziq8TBkjPuaYBI/ijbLigdPMEi81PsOpIXx3BXKCt27TLmUVHpFTWPa
u2NQUQl3k3Xc0H1sy1A+jmjfvCyqWxTOU1IY4rlzRKHdp+D1oCz5iKfyfUko
ktAZgqOMx5pWL975YhM793MS8aYqhOdQpeuW401fm18xxwE4x6svSSys+qq8
MdkL/i7YVjUKr/M8SIrGPb/IjKwClM7jfpN+sHv0p/GcQ7J1kmXYUdA6AJp5
Z0vYk4aPcMSlrPwdRX21I9w=
=zXfe
-----END PGP SIGNATURE-----
"; 

MemoryStream messageStream = new MemoryStream(Encoding.ASCII.GetBytes(message));
MemoryStream keyStream = new MemoryStream(Encoding.ASCII.GetBytes(key));

try {
    var msg= VerifyFile(messageStream, 
            PgpUtilities.GetDecoderStream(keyStream));
    // verification passes msg is the content of the message
} catch (Exception e) {
    // verification fails
}

这是实现:

private static String VerifyFile(Stream inputStream, Stream keyIn)
    {
        ArmoredInputStream aIn = new ArmoredInputStream(inputStream);
        MemoryStream outStr = new MemoryStream(); // File.Create(resultName);


        //
        // write out signed section using the local line separator.
        // note: trailing white space needs to be removed from the end of
        // each line RFC 4880 Section 7.1
        //
        MemoryStream lineOut = new MemoryStream();
        int lookAhead = ReadInputLine(lineOut, aIn);
        byte[] lineSep = LineSeparator;

        if (lookAhead != -1 && aIn.IsClearText())
        {
            byte[] line = lineOut.ToArray();
            outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
            outStr.Write(lineSep, 0, lineSep.Length);

            while (lookAhead != -1 && aIn.IsClearText())
            {
                lookAhead = ReadInputLine(lineOut, lookAhead, aIn);

                line = lineOut.ToArray();
                outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                outStr.Write(lineSep, 0, lineSep.Length);
            }
        }
        else
        {
            // a single line file
            if (lookAhead != -1)
            {
                byte[] line = lineOut.ToArray();
                outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                outStr.Write(lineSep, 0, lineSep.Length);
            }
        }
        outStr.Flush();
        //outStr.Close();


        PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(keyIn);

        PgpObjectFactory pgpFact = new PgpObjectFactory(aIn);
        PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
        PgpSignature sig = p3[0];

        var key = pgpRings.GetPublicKey(sig.KeyId);
        if (key == null)
        {
            throw new Exception("Can't verify the message signature.");
        }
        sig.InitVerify(key);

        //
        // read the input, making sure we ignore the last newline.
        //
        outStr.Seek(0, SeekOrigin.Begin);
        StreamReader reader = new StreamReader(outStr);
        string messageContent = reader.ReadToEnd();

        outStr.Seek(0, SeekOrigin.Begin);

        Stream sigIn = outStr; //File.OpenRead(resultName);

        lookAhead = ReadInputLine(lineOut, sigIn);

        ProcessLine(sig, lineOut.ToArray());

        if (lookAhead != -1)
        {
            do
            {
                lookAhead = ReadInputLine(lineOut, lookAhead, sigIn);

                sig.Update((byte)'\r');
                sig.Update((byte)'\n');

                ProcessLine(sig, lineOut.ToArray());
            }
            while (lookAhead != -1);
        }

        sigIn.Close();

        if (sig.Verify()) {
            // signature verified
            return messageContent;
        } else {
            // signature verification failed
            throw new Exception("Can't verify the message signature.");
        }
    }


    private static int ReadInputLine(
            MemoryStream bOut,
            Stream fIn)
    {
        bOut.SetLength(0);

        int lookAhead = -1;
        int ch;

        while ((ch = fIn.ReadByte()) >= 0)
        {
            bOut.WriteByte((byte)ch);
            if (ch == '\r' || ch == '\n')
            {
                lookAhead = ReadPassedEol(bOut, ch, fIn);
                break;
            }
        }

        return lookAhead;
    }

    private static int ReadPassedEol(
        MemoryStream bOut,
        int lastCh,
        Stream fIn)
    {
        int lookAhead = fIn.ReadByte();

        if (lastCh == '\r' && lookAhead == '\n')
        {
            bOut.WriteByte((byte)lookAhead);
            lookAhead = fIn.ReadByte();
        }

        return lookAhead;
    }

    private static void ProcessLine(
            PgpSignature sig,
            byte[] line)
    {
        // note: trailing white space needs to be removed from the end of
        // each line for signature calculation RFC 4880 Section 7.1
        int length = GetLengthWithoutWhiteSpace(line);
        if (length > 0)
        {
            sig.Update(line, 0, length);
        }
    }

    private static void ProcessLine(
        Stream aOut,
        PgpSignatureGenerator sGen,
        byte[] line)
    {
        int length = GetLengthWithoutWhiteSpace(line);
        if (length > 0)
        {
            sGen.Update(line, 0, length);
        }

        aOut.Write(line, 0, line.Length);
    }

    private static int GetLengthWithoutSeparatorOrTrailingWhitespace(byte[] line)
    {
        int end = line.Length - 1;

        while (end >= 0 && IsWhiteSpace(line[end]))
        {
            end--;
        }

        return end + 1;
    }

    private static bool IsLineEnding(
        byte b)
    {
        return b == '\r' || b == '\n';
    }

    private static int GetLengthWithoutWhiteSpace(
        byte[] line)
    {
        int end = line.Length - 1;

        while (end >= 0 && IsWhiteSpace(line[end]))
        {
            end--;
        }

        return end + 1;
    }

    private static bool IsWhiteSpace(
        byte b)
    {
        return IsLineEnding(b) || b == '\t' || b == ' ';
    }

    private static int ReadInputLine(
        MemoryStream bOut,
        int lookAhead,
        Stream fIn)
    {
        bOut.SetLength(0);

        int ch = lookAhead;

        do
        {
            bOut.WriteByte((byte)ch);
            if (ch == '\r' || ch == '\n')
            {
                lookAhead = ReadPassedEol(bOut, ch, fIn);
                break;
            }
        }
        while ((ch = fIn.ReadByte()) >= 0);

        if (ch < 0)
        {
            lookAhead = -1;
        }

        return lookAhead;
    }

    private static byte[] LineSeparator
    {
        get { return Encoding.ASCII.GetBytes(Environment.NewLine); }
    }

Following Seer's suggestion to look at this example I finally got message verification running.

I have method VerifyFile which takes signed message and public key and returns the content of the message if the verification passes. For example it can be used like this:

string key = @"-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG C# v1.6.1.0

mQENBFpc87wBCACK5FG6Z70iovzSzQF7OEB/YbKF7SPS1/GZAQhp/2n2G8x5Lxj5
/CKqR8JLj1+222unuWgfqvfny0fLvttt1r6lAH/kqDYMBg26GTbZy93R5BYatBjd
pzYl/lIyKxc/QwDdZm8zNxeUpDSfoe9jVULOg0MiMDtdQupOf6CanlEioXfyf88F
1BLcJyFSckaYieosBw5hnnI+1cZZ3k+4HpDJJslVzngfTPWRibtN5PKff1CKP55E
ME99XkuPDaNL7XZmu7lZSEUN3jJFVydZQrDkvxddihzV4pTgRI3gDAFoJxxIYZX3
JsQAJItlqq8bBsQ+bKPikgAiMySGcEi+ilI5ABEBAAG0GnNoYWxhbWFub3YubWFy
aW5AZ21haWwuY29tiQEcBBABAgAGBQJaXPO8AAoJEBvHdfmVFHzkvHEH/179VAdH
gWRN5HVprsp4vHP3q1CJV9j+fPlQIZU3JEwrM+INxzpfSqZeN4NwB7yoo2NCdCNP
Ndg8zhiuEYM51hNtqU5cwYBcaAbm1so6TSVo8i4nrfN3+oDYEfYPqglNrd1V233J
oyLriwpGkR6RBYMY2q2Re+EFNR1bxUmeE0wnb8FOodRCSh0Wd3Iy9mvmhv5voHIr
aZzgsuifGw1JilSu9+RoC6b1CHb9jUkWQ/odkTvl5/rxA14TKstgoLoSLHktYQfw
le6B8+lPtmODtagWoDEeR/M0zm/wyCOt5wqjjJCgvaipUaA+oiijIYwCpqUBwfm3
DZ9DStGHGVxQQnc=
=s91O
-----END PGP PUBLIC KEY BLOCK-----
";
string message = @"-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test tes tes ts tse tse t
-----BEGIN PGP SIGNATURE-----
Version: OpenPGP.js v1.0.1
Comment: http://openpgpjs.org

wsBcBAEBCAAQBQJaXP5WCRAbx3X5lRR85AAAUcoH/jtcyWcpTVyXyz/ptWLo
Hx+g51EeeA0Hpq7kZCXu4FuyhNn/QvnvKyt9qegxQoRSZhT37ln8t80NW6sS
B4XVFziq8TBkjPuaYBI/ijbLigdPMEi81PsOpIXx3BXKCt27TLmUVHpFTWPa
u2NQUQl3k3Xc0H1sy1A+jmjfvCyqWxTOU1IY4rlzRKHdp+D1oCz5iKfyfUko
ktAZgqOMx5pWL975YhM793MS8aYqhOdQpeuW401fm18xxwE4x6svSSys+qq8
MdkL/i7YVjUKr/M8SIrGPb/IjKwClM7jfpN+sHv0p/GcQ7J1kmXYUdA6AJp5
Z0vYk4aPcMSlrPwdRX21I9w=
=zXfe
-----END PGP SIGNATURE-----
"; 

MemoryStream messageStream = new MemoryStream(Encoding.ASCII.GetBytes(message));
MemoryStream keyStream = new MemoryStream(Encoding.ASCII.GetBytes(key));

try {
    var msg= VerifyFile(messageStream, 
            PgpUtilities.GetDecoderStream(keyStream));
    // verification passes msg is the content of the message
} catch (Exception e) {
    // verification fails
}

And here is the implementation:

private static String VerifyFile(Stream inputStream, Stream keyIn)
    {
        ArmoredInputStream aIn = new ArmoredInputStream(inputStream);
        MemoryStream outStr = new MemoryStream(); // File.Create(resultName);


        //
        // write out signed section using the local line separator.
        // note: trailing white space needs to be removed from the end of
        // each line RFC 4880 Section 7.1
        //
        MemoryStream lineOut = new MemoryStream();
        int lookAhead = ReadInputLine(lineOut, aIn);
        byte[] lineSep = LineSeparator;

        if (lookAhead != -1 && aIn.IsClearText())
        {
            byte[] line = lineOut.ToArray();
            outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
            outStr.Write(lineSep, 0, lineSep.Length);

            while (lookAhead != -1 && aIn.IsClearText())
            {
                lookAhead = ReadInputLine(lineOut, lookAhead, aIn);

                line = lineOut.ToArray();
                outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                outStr.Write(lineSep, 0, lineSep.Length);
            }
        }
        else
        {
            // a single line file
            if (lookAhead != -1)
            {
                byte[] line = lineOut.ToArray();
                outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line));
                outStr.Write(lineSep, 0, lineSep.Length);
            }
        }
        outStr.Flush();
        //outStr.Close();


        PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(keyIn);

        PgpObjectFactory pgpFact = new PgpObjectFactory(aIn);
        PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
        PgpSignature sig = p3[0];

        var key = pgpRings.GetPublicKey(sig.KeyId);
        if (key == null)
        {
            throw new Exception("Can't verify the message signature.");
        }
        sig.InitVerify(key);

        //
        // read the input, making sure we ignore the last newline.
        //
        outStr.Seek(0, SeekOrigin.Begin);
        StreamReader reader = new StreamReader(outStr);
        string messageContent = reader.ReadToEnd();

        outStr.Seek(0, SeekOrigin.Begin);

        Stream sigIn = outStr; //File.OpenRead(resultName);

        lookAhead = ReadInputLine(lineOut, sigIn);

        ProcessLine(sig, lineOut.ToArray());

        if (lookAhead != -1)
        {
            do
            {
                lookAhead = ReadInputLine(lineOut, lookAhead, sigIn);

                sig.Update((byte)'\r');
                sig.Update((byte)'\n');

                ProcessLine(sig, lineOut.ToArray());
            }
            while (lookAhead != -1);
        }

        sigIn.Close();

        if (sig.Verify()) {
            // signature verified
            return messageContent;
        } else {
            // signature verification failed
            throw new Exception("Can't verify the message signature.");
        }
    }


    private static int ReadInputLine(
            MemoryStream bOut,
            Stream fIn)
    {
        bOut.SetLength(0);

        int lookAhead = -1;
        int ch;

        while ((ch = fIn.ReadByte()) >= 0)
        {
            bOut.WriteByte((byte)ch);
            if (ch == '\r' || ch == '\n')
            {
                lookAhead = ReadPassedEol(bOut, ch, fIn);
                break;
            }
        }

        return lookAhead;
    }

    private static int ReadPassedEol(
        MemoryStream bOut,
        int lastCh,
        Stream fIn)
    {
        int lookAhead = fIn.ReadByte();

        if (lastCh == '\r' && lookAhead == '\n')
        {
            bOut.WriteByte((byte)lookAhead);
            lookAhead = fIn.ReadByte();
        }

        return lookAhead;
    }

    private static void ProcessLine(
            PgpSignature sig,
            byte[] line)
    {
        // note: trailing white space needs to be removed from the end of
        // each line for signature calculation RFC 4880 Section 7.1
        int length = GetLengthWithoutWhiteSpace(line);
        if (length > 0)
        {
            sig.Update(line, 0, length);
        }
    }

    private static void ProcessLine(
        Stream aOut,
        PgpSignatureGenerator sGen,
        byte[] line)
    {
        int length = GetLengthWithoutWhiteSpace(line);
        if (length > 0)
        {
            sGen.Update(line, 0, length);
        }

        aOut.Write(line, 0, line.Length);
    }

    private static int GetLengthWithoutSeparatorOrTrailingWhitespace(byte[] line)
    {
        int end = line.Length - 1;

        while (end >= 0 && IsWhiteSpace(line[end]))
        {
            end--;
        }

        return end + 1;
    }

    private static bool IsLineEnding(
        byte b)
    {
        return b == '\r' || b == '\n';
    }

    private static int GetLengthWithoutWhiteSpace(
        byte[] line)
    {
        int end = line.Length - 1;

        while (end >= 0 && IsWhiteSpace(line[end]))
        {
            end--;
        }

        return end + 1;
    }

    private static bool IsWhiteSpace(
        byte b)
    {
        return IsLineEnding(b) || b == '\t' || b == ' ';
    }

    private static int ReadInputLine(
        MemoryStream bOut,
        int lookAhead,
        Stream fIn)
    {
        bOut.SetLength(0);

        int ch = lookAhead;

        do
        {
            bOut.WriteByte((byte)ch);
            if (ch == '\r' || ch == '\n')
            {
                lookAhead = ReadPassedEol(bOut, ch, fIn);
                break;
            }
        }
        while ((ch = fIn.ReadByte()) >= 0);

        if (ch < 0)
        {
            lookAhead = -1;
        }

        return lookAhead;
    }

    private static byte[] LineSeparator
    {
        get { return Encoding.ASCII.GetBytes(Environment.NewLine); }
    }
呆° 2024-11-26 10:09:09
using System;
using System.Collections;
using System.IO;


using Org.BouncyCastle.Bcpg.OpenPgp;

namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
{
    /**
    * A simple utility class that signs and verifies files.
    * <p>
    * To sign a file: SignedFileProcessor -s [-a] fileName secretKey passPhrase.<br/>
    * If -a is specified the output file will be "ascii-armored".</p>
    * <p>
    * To decrypt: SignedFileProcessor -v fileName publicKeyFile.</p>
    * <p>
    * <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
    * will have been used.</p>
    * <p>
    * <b>Note</b>: the example also makes use of PGP compression. If you are having difficulty Getting it
    * to interoperate with other PGP programs try removing the use of compression first.</p>
    */
    public sealed class SignedFileProcessor
    {
        private SignedFileProcessor() {}

        /**
        * verify the passed in file as being correctly signed.
        */
        private static void VerifyFile(
            Stream  inputStream,
            Stream  keyIn)
        {
            inputStream = PgpUtilities.GetDecoderStream(inputStream);

            PgpObjectFactory            pgpFact = new PgpObjectFactory(inputStream);
            PgpCompressedData           c1 = (PgpCompressedData) pgpFact.NextPgpObject();
            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpOnePassSignatureList     p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject();
            PgpOnePassSignature         ops = p1[0];

            PgpLiteralData              p2 = (PgpLiteralData) pgpFact.NextPgpObject();
            Stream                      dIn = p2.GetInputStream();
            PgpPublicKeyRingBundle      pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn));
            PgpPublicKey                key = pgpRing.GetPublicKey(ops.KeyId);
            Stream                      fos = File.Create(p2.FileName);

            ops.InitVerify(key);

            int ch;
            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
                fos.WriteByte((byte) ch);
            }
            fos.Close();

            PgpSignatureList    p3 = (PgpSignatureList)pgpFact.NextPgpObject();
            PgpSignature        firstSig = p3[0];
            if (ops.Verify(firstSig))
            {
                Console.Out.WriteLine("signature verified.");
            }
            else
            {
                Console.Out.WriteLine("signature verification failed.");
            }
        }

        /**
        * Generate an encapsulated signed file.
        *
        * @param fileName
        * @param keyIn
        * @param outputStream
        * @param pass
        * @param armor
        */
        private static void SignFile(
            string  fileName,
            Stream  keyIn,
            Stream  outputStream,
            char[]  pass,
            bool    armor,
            bool    compress)
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);
            }

            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
            foreach (string userId in pgpSec.PublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
                spGen.SetSignerUserId(false, userId);
                sGen.SetHashedSubpackets(spGen.Generate());
                // Just the first one!
                break;
            }

            Stream cOut = outputStream;
            PgpCompressedDataGenerator cGen = null;
            if (compress)
            {
                cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);

                cOut = cGen.Open(cOut);
            }

            BcpgOutputStream bOut = new BcpgOutputStream(cOut);

            sGen.GenerateOnePassVersion(false).Encode(bOut);

            FileInfo                    file = new FileInfo(fileName);
            PgpLiteralDataGenerator     lGen = new PgpLiteralDataGenerator();
            Stream                      lOut = lGen.Open(bOut, PgpLiteralData.Binary, file);
            FileStream                  fIn = file.OpenRead();
            int                         ch = 0;

            while ((ch = fIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte) ch);
                sGen.Update((byte)ch);
            }

            fIn.Close();
            lGen.Close();

            sGen.Generate().Encode(bOut);

            if (cGen != null)
            {
                cGen.Close();
            }

            if (armor)
            {
                outputStream.Close();
            }
        }

        public static void Main(
            string[] args)
        {
            // TODO provide command-line option to determine whether to use compression in SignFile
            if (args[0].Equals("-s"))
            {
                Stream keyIn, fos;
                if (args[1].Equals("-a"))
                {
                    keyIn = File.OpenRead(args[3]);
                    fos = File.Create(args[2] + ".asc");

                    SignFile(args[2], keyIn, fos, args[4].ToCharArray(), true, true);
                }
                else
                {
                    keyIn = File.OpenRead(args[2]);
                    fos = File.Create(args[1] + ".bpg");

                    SignFile(args[1], keyIn, fos, args[3].ToCharArray(), false, true);
                }
                keyIn.Close();
                fos.Close();
            }
            else if (args[0].Equals("-v"))
            {
                using (Stream fis = File.OpenRead(args[1]),
                    keyIn = File.OpenRead(args[2]))
                {
                    VerifyFile(fis, keyIn);
                }
            }
            else
            {
                Console.Error.WriteLine("usage: SignedFileProcessor -v|-s [-a] file keyfile [passPhrase]");
            }
        }
    }
}
using System;
using System.Collections;
using System.IO;


using Org.BouncyCastle.Bcpg.OpenPgp;

namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
{
    /**
    * A simple utility class that signs and verifies files.
    * <p>
    * To sign a file: SignedFileProcessor -s [-a] fileName secretKey passPhrase.<br/>
    * If -a is specified the output file will be "ascii-armored".</p>
    * <p>
    * To decrypt: SignedFileProcessor -v fileName publicKeyFile.</p>
    * <p>
    * <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
    * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
    * will have been used.</p>
    * <p>
    * <b>Note</b>: the example also makes use of PGP compression. If you are having difficulty Getting it
    * to interoperate with other PGP programs try removing the use of compression first.</p>
    */
    public sealed class SignedFileProcessor
    {
        private SignedFileProcessor() {}

        /**
        * verify the passed in file as being correctly signed.
        */
        private static void VerifyFile(
            Stream  inputStream,
            Stream  keyIn)
        {
            inputStream = PgpUtilities.GetDecoderStream(inputStream);

            PgpObjectFactory            pgpFact = new PgpObjectFactory(inputStream);
            PgpCompressedData           c1 = (PgpCompressedData) pgpFact.NextPgpObject();
            pgpFact = new PgpObjectFactory(c1.GetDataStream());

            PgpOnePassSignatureList     p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject();
            PgpOnePassSignature         ops = p1[0];

            PgpLiteralData              p2 = (PgpLiteralData) pgpFact.NextPgpObject();
            Stream                      dIn = p2.GetInputStream();
            PgpPublicKeyRingBundle      pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn));
            PgpPublicKey                key = pgpRing.GetPublicKey(ops.KeyId);
            Stream                      fos = File.Create(p2.FileName);

            ops.InitVerify(key);

            int ch;
            while ((ch = dIn.ReadByte()) >= 0)
            {
                ops.Update((byte)ch);
                fos.WriteByte((byte) ch);
            }
            fos.Close();

            PgpSignatureList    p3 = (PgpSignatureList)pgpFact.NextPgpObject();
            PgpSignature        firstSig = p3[0];
            if (ops.Verify(firstSig))
            {
                Console.Out.WriteLine("signature verified.");
            }
            else
            {
                Console.Out.WriteLine("signature verification failed.");
            }
        }

        /**
        * Generate an encapsulated signed file.
        *
        * @param fileName
        * @param keyIn
        * @param outputStream
        * @param pass
        * @param armor
        */
        private static void SignFile(
            string  fileName,
            Stream  keyIn,
            Stream  outputStream,
            char[]  pass,
            bool    armor,
            bool    compress)
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);
            }

            PgpSecretKey pgpSec = PgpExampleUtilities.ReadSecretKey(keyIn);
            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha1);

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
            foreach (string userId in pgpSec.PublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
                spGen.SetSignerUserId(false, userId);
                sGen.SetHashedSubpackets(spGen.Generate());
                // Just the first one!
                break;
            }

            Stream cOut = outputStream;
            PgpCompressedDataGenerator cGen = null;
            if (compress)
            {
                cGen = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib);

                cOut = cGen.Open(cOut);
            }

            BcpgOutputStream bOut = new BcpgOutputStream(cOut);

            sGen.GenerateOnePassVersion(false).Encode(bOut);

            FileInfo                    file = new FileInfo(fileName);
            PgpLiteralDataGenerator     lGen = new PgpLiteralDataGenerator();
            Stream                      lOut = lGen.Open(bOut, PgpLiteralData.Binary, file);
            FileStream                  fIn = file.OpenRead();
            int                         ch = 0;

            while ((ch = fIn.ReadByte()) >= 0)
            {
                lOut.WriteByte((byte) ch);
                sGen.Update((byte)ch);
            }

            fIn.Close();
            lGen.Close();

            sGen.Generate().Encode(bOut);

            if (cGen != null)
            {
                cGen.Close();
            }

            if (armor)
            {
                outputStream.Close();
            }
        }

        public static void Main(
            string[] args)
        {
            // TODO provide command-line option to determine whether to use compression in SignFile
            if (args[0].Equals("-s"))
            {
                Stream keyIn, fos;
                if (args[1].Equals("-a"))
                {
                    keyIn = File.OpenRead(args[3]);
                    fos = File.Create(args[2] + ".asc");

                    SignFile(args[2], keyIn, fos, args[4].ToCharArray(), true, true);
                }
                else
                {
                    keyIn = File.OpenRead(args[2]);
                    fos = File.Create(args[1] + ".bpg");

                    SignFile(args[1], keyIn, fos, args[3].ToCharArray(), false, true);
                }
                keyIn.Close();
                fos.Close();
            }
            else if (args[0].Equals("-v"))
            {
                using (Stream fis = File.OpenRead(args[1]),
                    keyIn = File.OpenRead(args[2]))
                {
                    VerifyFile(fis, keyIn);
                }
            }
            else
            {
                Console.Error.WriteLine("usage: SignedFileProcessor -v|-s [-a] file keyfile [passPhrase]");
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文