Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用PGP机制对文本文件进行数字签名_C#_Pgp - Fatal编程技术网

C# 如何使用PGP机制对文本文件进行数字签名

C# 如何使用PGP机制对文本文件进行数字签名,c#,pgp,C#,Pgp,我有一个文本文件,我需要使用PGP方法对文本文件进行数字签名,并将签名附在文件上。请查看。它适合你的需要吗 您也可以使用Bouncy Castle,堆栈溢出的一个例子是。如下所示: using Org.BouncyCastle.Bcpg; using Org.BouncyCastle.Bcpg.OpenPgp; using Org.BouncyCastle.Security; namespace BouncyCastleTest.PGP { // http://www.progra

我有一个文本文件,我需要使用PGP方法对文本文件进行数字签名,并将签名附在文件上。

请查看。它适合你的需要吗

您也可以使用Bouncy Castle,堆栈溢出的一个例子是。

如下所示:

using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Security;


namespace BouncyCastleTest.PGP
{

    // http://www.programcreek.com/java-api-examples/index.php?api=org.bouncycastle.bcpg.HashAlgorithmTags
    // http://stackoverflow.com/questions/6337985/how-to-sign-a-txt-file-with-a-pgp-key-in-c-sharp-using-bouncy-castle-library
    class SignOnly
    {


        public void SignFile(string hashAlgorithm, string fileName, System.IO.Stream privateKeyStream
            , string privateKeyPassword, System.IO.Stream outStream)
        {

            PgpSecretKey pgpSec = ReadSigningSecretKey(privateKeyStream);
            PgpPrivateKey pgpPrivKey = null;

            pgpPrivKey = pgpSec.ExtractPrivateKey(privateKeyPassword.ToCharArray());




            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, ParseHashAlgorithm(hashAlgorithm));

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);

            foreach (string userId in pgpSec.PublicKey.GetUserIds())
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();

                spGen.SetSignerUserId(false, userId);
                sGen.SetHashedSubpackets(spGen.Generate());
            }

            CompressionAlgorithmTag compression = PreferredCompression(pgpSec.PublicKey);
            PgpCompressedDataGenerator cGen = new PgpCompressedDataGenerator(compression);

            BcpgOutputStream bOut = new BcpgOutputStream(cGen.Open(outStream));
            sGen.GenerateOnePassVersion(false).Encode(bOut);

            System.IO.FileInfo file = new System.IO.FileInfo(fileName);
            System.IO.FileStream fIn = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
            PgpLiteralDataGenerator lGen = new PgpLiteralDataGenerator();
            System.IO.Stream lOut = lGen.Open(bOut, PgpLiteralData.Binary, file);

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

            fIn.Close();
            sGen.Generate().Encode(bOut);
            lGen.Close();
            cGen.Close();
            outStream.Close();
        }


        public static PgpSecretKeyRingBundle CreatePgpSecretKeyRingBundle(System.IO.Stream keyInStream)
        {
            return new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(keyInStream));
        }


        public PgpSecretKey ReadSigningSecretKey(System.IO.Stream keyInStream) 
        {
            PgpSecretKeyRingBundle pgpSec = CreatePgpSecretKeyRingBundle(keyInStream);
            PgpSecretKey key = null;
            System.Collections.IEnumerator rIt = pgpSec.GetKeyRings().GetEnumerator();
            while (key == null && rIt.MoveNext())
            {
                PgpSecretKeyRing kRing = (PgpSecretKeyRing)rIt.Current;
                System.Collections.IEnumerator kIt = kRing.GetSecretKeys().GetEnumerator();
                while (key == null && kIt.MoveNext())
                {
                    PgpSecretKey k = (PgpSecretKey)kIt.Current;
                    if (k.IsSigningKey)
                        key = k;
                }
            }

            if (key == null)
                throw new System.Exception("Wrong private key - Can't find signing key in key ring.");
            else
                return key;
        }



        public static string GetDigestName(int hashAlgorithm)
        {
            switch ((Org.BouncyCastle.Bcpg.HashAlgorithmTag)hashAlgorithm)
            {
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha1:
                    return "SHA1";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.MD2:
                    return "MD2";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.MD5:
                    return "MD5";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.RipeMD160:
                    return "RIPEMD160";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha256:
                    return "SHA256";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha384:
                    return "SHA384";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha512:
                    return "SHA512";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha224:
                    return "SHA224";
                case Org.BouncyCastle.Bcpg.HashAlgorithmTag.Tiger192:
                    return "TIGER";
                default:
                    throw new Org.BouncyCastle.Bcpg.OpenPgp.PgpException("unknown hash algorithm tag in GetDigestName: " + hashAlgorithm);
            }
        }


        public static Org.BouncyCastle.Bcpg.HashAlgorithmTag ParseHashAlgorithm(string hashAlgorithm)
        {
            switch (hashAlgorithm.ToUpper())
            {
                case "SHA1":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha1;
                case "MD2":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.MD2;
                case "MD5":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.MD5;
                case "RIPEMD160":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.RipeMD160;
                case "SHA256":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha256;
                case "SHA384":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha384;
                case "SHA512":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha512;
                case "SHA224":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.Sha224;
                case "TIGER":
                    return Org.BouncyCastle.Bcpg.HashAlgorithmTag.Tiger192;
                default:
                    throw new Org.BouncyCastle.Bcpg.OpenPgp.PgpException("unknown hash algorithm name in ParseHashAlgorithm: " + hashAlgorithm);
            }
        }


        public static CompressionAlgorithmTag PreferredCompression(PgpPublicKey publicKey)
        {
            //return CompressionAlgorithmTag.BZip2;
            return CompressionAlgorithmTag.Uncompressed;
        }

    }


}
BouncyCastle源代码中还有很多示例:

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]");
            }
        }
    }
}
使用系统;
使用系统集合;
使用System.IO;
使用Org.BouncyCastle.Bcpg.OpenPgp;
名称空间Org.bounchycastle.Bcpg.OpenPgp.Examples
{
/**
*对文件进行签名和验证的简单实用程序类。
*
*签署文件:SignedFileProcessor-s[-a]fileName secretKey密码短语。
*如果指定了-a,则输出文件将为“ascii铠装”

* *要解密:SignedFileProcessor-v fileName publicKeyFile

* *注意:此示例将以静默方式覆盖文件,也不会注意 *文件名中“_CONSOLE”的规范。它还需要一个传递短语 *将被使用

* *注意:该示例还使用PGP压缩。如果您在获取它时遇到困难 *要与其他PGP程序进行互操作,请先尝试取消使用压缩

*/ 公共密封类SignedFileProcessor { 私有SignedFileProcessor(){} /** *验证传入的文件是否已正确签名。 */ 私有静态无效验证文件( 流输入流, 流键控) { inputStream=PgpUtilities.GetDecoderStream(inputStream); PgpObjectFactory pgpFact=新的PgpObjectFactory(inputStream); PgpCompressedData c1=(PgpCompressedData)pgpFact.nextpgobject(); pgpFact=新的PgpObjectFactory(c1.GetDataStream()); PgpOnePassSignatureList p1=(PgpOnePassSignatureList)pgpFact.nextPGObject(); PgpOnePassSignature ops=p1[0]; PgpLiteralData p2=(PgpLiteralData)pgpFact.nextpgobject(); Stream dIn=p2.GetInputStream(); pgppublickeringbundle pgpRing=新的pgppublickeringbundle(PgpUtilities.GetDecoderStream(keyIn)); PgpPublicKey=pgpRing.GetPublicKey(ops.KeyId); Stream fos=File.Create(p2.FileName); 操作初始验证(密钥); int-ch; 而((ch=dIn.ReadByte())>=0) { 操作更新((字节)ch); fos.WriteByte((字节)ch); } fos.Close(); PgpSignatureList p3=(PgpSignatureList)pgpFact.NextPgpObject(); PgpSignature firstSig=p3[0]; if(运行验证(第一信号)) { Console.Out.WriteLine(“签名已验证”); } 其他的 { Console.Out.WriteLine(“签名验证失败”); } } /** *生成一个封装的签名文件。 * *@param文件名 *@param-keyIn *@param outputStream *@param pass *@param装甲 */ 私有静态无效签名文件( 字符串文件名, 流键因, 流输出流, char[]pass, 布尔盔甲, bool(压缩) { if(装甲) { outputStream=新ArmoreOutputStream(outputStream); } PgpSecretKey pgpSec=PgpExampleUtilities.ReadSecretKey(keyIn); PgpPrivateKey pgpPrivKey=pgpSec.ExtractPrivateKey(通过); PgpSignatureGenerator sGen=新的PgpSignatureGenerator(pgpSec.PublicKey.Algorithm,HashAlgorithmTag.Sha1); sGen.InitSign(PgpSignature.BinaryDocument,pgpPrivKey); foreach(pgpSec.PublicKey.GetUserIds()中的字符串userId) { PgpSignatureSubpacketGenerator spGen=新的PgpSignatureSubpacketGenerator(); spGen.SetSignerUserId(false,userId); sGen.SetHashedSubpackets(spGen.Generate()); //就第一个! 打破 } Stream cOut=outputStream; PgpCompressedDataGenerator cGen=null; 如果(压缩) { cGen=新的PGP压缩数据发生器(CompressionAlgorithmTag.ZLib); cOut=cGen.Open(cOut); } BcpgOutputStream bOut=新的BcpgOutputStream(cOut); sGen.GenerateOnePassVersion(false).编码(bOut); FileInfo file=新的FileInfo(文件名); PgpLiteralDataGenerator lGen=新的PgpLiteralDataGenerator(); Stream lOut=lGen.Open(bOut,PgpLiteralData.Binary,file); FileStream fIn=file.OpenRead(); int ch=0; 而((ch=fIn.ReadByte())>=0) { lOut.WriteByte((字节)ch); sGen.Update((字节)ch); } fIn.Close(); lGen.Close(); sGen.Generate().Encode(bOut); 如果(cGen!=null) { cGen.Close(); } if(装甲) { outputStream.Close(); } } 公共静态真空总管( 字符串[]args) { //TODO提供命令行选项以确定是否在SignFile中使用压缩 如果(args[0]。等于(“-s”)) { Stream-keyIn,fos; if(args[1]。等于(“-a”)) { keyIn=File.OpenRead(args[3]); fos=File.Create(args[2]+“.asc”); 签名文件(args[2],键入,fos,args[4]。ToCha