Example #1
0
        /*.......................................................................數位簽章開始*/


        private static void SignFile(
            string fileName,     //欲作簽章的檔案名稱及位置
            Stream keyIn,        // Private key 的 File Stream
            Stream outputStream, //簽章後的檔案 File Stream
            char[] pass,         // private Key 的 password
            bool armor,          //用途不明?? 範例預設true
            bool compress        //用途不明?? 範例預設true
            )
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);
            }
            PgpSecretKey          pgpSec     = PgpExampleUtilities.ReadSecretKey(keyIn);
            PgpPrivateKey         pgpPrivKey = pgpSec.ExtractPrivateKey(pass);
            PgpSignatureGenerator sGen       = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha256);

            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();
            }
        }
Example #2
0
        /*.......................................................................加密開始*/


        /*文章 -> Session Key(對稱式) - > 文章加密 - - - - - -> 加密後的文章
         *     -> Session Key(對稱式) - > 公鑰(對方)加密 - - -> 加密後的Session Key
         */


        //外部呼叫的 method
        public static void EncryptFile(
            string outputFileName,  //加密後輸出檔案名稱位置
            string inputFileName,   //欲加密檔案名稱位置
            string encKeyFileName,  //提供加密的 public key(接收方的) 檔名及位置
            bool armor,             //盔甲??,範例預設為true
            bool withIntegrityCheck //完整性檢查,範例預設為false
            )
        {
            PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName); //find encryption key

            using (Stream output = File.Create(outputFileName))
            {
                EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck);
            }
        }
Example #3
0
        /*文章 -> Session Key(對稱式) - > 文章加密 - - - - - -> 加密後的文章
         *     -> Session Key(對稱式) - > 公鑰(對方)加密 - - -> 加密後的Session Key
         */

        //內部的實作參照官方範例
        private static void EncryptFile(
            Stream outputStream, //加密後輸出檔案之資料流
            string fileName,     //欲加密檔案名稱位置
            PgpPublicKey encKey, //接收方的公鑰(對方)
            bool armor,
            bool withIntegrityCheck /*完整性檢查*/)
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream); //位置、headers、雜湊表
            }

            try
            {
                byte[] bytes = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip); //資料壓縮一個檔案

                PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
                    SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); //隨機產生Session Key(對稱-Cast5)

                encGen.AddMethod(encKey);

                Stream cOut = encGen.Open(outputStream, bytes.Length); //建立 todo 注意,RSA非對稱加密,公鑰加密私鑰解密,預設為SHA1,但可選擇 SHA256雜湊

                cOut.Write(bytes, 0, bytes.Length);                    //加密及寫入
                cOut.Close();

                if (armor)
                {
                    outputStream.Close();
                    outputStream.Dispose();
                }
            }
            catch (PgpException e)
            {
                Console.Error.WriteLine(e);

                Exception underlyingException = e.InnerException;
                if (underlyingException != null)
                {
                    Console.Error.WriteLine(underlyingException.Message);
                    Console.Error.WriteLine(underlyingException.StackTrace);
                }
            }
        }
Example #4
0
        //內部的實作參照官方範例
        private static void EncryptFile(
            Stream outputStream,
            string fileName,
            PgpPublicKey encKey,
            bool armor,
            bool withIntegrityCheck)
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);
            }

            try
            {
                byte[] bytes = PgpExampleUtilities.CompressFile(fileName, CompressionAlgorithmTag.Zip);

                PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
                    SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
                encGen.AddMethod(encKey);

                Stream cOut = encGen.Open(outputStream, bytes.Length);

                cOut.Write(bytes, 0, bytes.Length);
                cOut.Close();

                if (armor)
                {
                    outputStream.Close();
                }
            }
            catch (PgpException e)
            {
                Console.Error.WriteLine(e);

                Exception underlyingException = e.InnerException;
                if (underlyingException != null)
                {
                    Console.Error.WriteLine(underlyingException.Message);
                    Console.Error.WriteLine(underlyingException.StackTrace);
                }
            }
        }
Example #5
0
        /*
         * 文章 -> hash -> 私鑰(自己)簽章 -> 簽章後的hash值
         * 文章 - - - - - - - - - - - - - -> 文章
         */


        /*.......................................................................數位簽章開始*/


        private static void SignFile(
            string fileName,     //預計數位簽章原始檔案的完整路徑
            Stream keyIn,        // Private key 的 File Stream (自己)
            Stream outputStream, //預計匯出(數位簽章後) File Stream
            char[] pass,         // private Key 的 password
            bool armor,          //盔甲??? 範例預設true
            bool compress        //解壓縮 範例預設true
            )
        {
            if (armor)
            {
                outputStream = new ArmoredOutputStream(outputStream);            //匯出位置、headers、雜湊表
            }
            PgpSecretKey  pgpSec     = PgpExampleUtilities.ReadSecretKey(keyIn); //PgpSecretKey包含私鑰及公鑰整個物件
            PgpPrivateKey pgpPrivKey = pgpSec.ExtractPrivateKey(pass);           //需輸入私鑰密碼才能取出私鑰

            /*
             * SHA是由美國國家安全局制定,主要應用於數字簽名標準裡面的數字簽名算法( DSA : Digital Signature Algorithm ),
             * SHA家族中以SHA1和SHA256最為廣泛使用。SHA1的雜湊值長度為160bit、SHA256則為256bit,長度越長碰撞的機會就越低也越安全,
             * 但同時計算的時間複雜度也隨著增高。
             */

            PgpSignatureGenerator sGen = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, HashAlgorithmTag.Sha256); //PublicKey.Algorithm即原始公鑰

            sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);                                                      //若沒私鑰重新生產一個

            foreach (string userId in pgpSec.PublicKey.GetUserIds())                                                     //ExportKeyPair 的 identity (MarkWu)
            {
                PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
                spGen.SetSignerUserId(false, userId);       //數位簽章的使用者
                sGen.SetHashedSubpackets(spGen.Generate()); //將 SignatureSubpacket 陣列化再回傳
                // 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);  //hash 加密

            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();
            }
        }
Example #6
0
        /*
         * 加密後的Session Key -> 私鑰(自己)解密 -> Session Key(對稱式)
         * 加密後的文章 - - - - - - - - - - - - - > Session Key(對稱式) -> 解密後的文章
         */


        private static void DecryptFile(
            Stream inputStream,    //欲解密之檔案之串流
            Stream keyIn,          //私鑰之串流
            char[] passwd,         //私鑰密碼
            string defaultFileName //解密後檔案名稱及位置
            )
        {
            inputStream = PgpUtilities.GetDecoderStream(inputStream); //資料流陣列化 byte Array

            try
            {
                PgpObjectFactory     pgpF = new PgpObjectFactory(inputStream);
                PgpEncryptedDataList enc;

                PgpObject o = pgpF.NextPgpObject();
                //
                // the first object might be a PGP marker packet.
                //
                if (o is PgpEncryptedDataList)
                {
                    enc = (PgpEncryptedDataList)o;
                }
                else
                {
                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
                }

                //
                // find the Secret Key
                //
                PgpPrivateKey             sKey   = null;
                PgpPublicKeyEncryptedData pbe    = null;
                PgpSecretKeyRingBundle    pgpSec = new PgpSecretKeyRingBundle(
                    PgpUtilities.GetDecoderStream(keyIn)); //new 密鑰捆包 物件

                foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
                {
                    sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd); //(密鑰捆包,identify,私鑰密碼),抓對稱加密的密鑰,密鑰

                    if (sKey != null)
                    {
                        pbe = pked;
                        break;
                    }
                }

                if (sKey == null)
                {
                    throw new ArgumentException("secret key for message not found.");
                }

                Stream clear = pbe.GetDataStream(sKey);                   //解碼

                PgpObjectFactory plainFact = new PgpObjectFactory(clear); // BcpgInputStream

                PgpObject message = plainFact.NextPgpObject();            //取出

                if (message is PgpCompressedData)
                {
                    PgpCompressedData cData   = (PgpCompressedData)message;
                    PgpObjectFactory  pgpFact = new PgpObjectFactory(cData.GetDataStream());

                    message = pgpFact.NextPgpObject(); //解壓縮
                }

                if (message is PgpLiteralData)
                {
                    PgpLiteralData ld = (PgpLiteralData)message; //內容

                    string outFileName = ld.FileName;
                    //if (outFileName.Length == 0)
                    //{
                    outFileName = defaultFileName;
                    //}

                    Stream fOut = File.Create(outFileName);
                    Stream unc  = ld.GetInputStream();
                    Streams.PipeAll(unc, fOut); //Pipe一種傳輸方式,存入匯出檔案
                    fOut.Close();
                    fOut.Dispose();
                }
                else if (message is PgpOnePassSignatureList)
                {
                    throw new PgpException("encrypted message contains a signed message - not literal data.");
                }
                else
                {
                    throw new PgpException("message is not a simple encrypted file - type unknown.");
                }

                if (pbe.IsIntegrityProtected())
                {
                    if (!pbe.Verify())
                    {
                        Console.Error.WriteLine("message failed integrity check");
                    }
                    else
                    {
                        Console.Error.WriteLine("message integrity check passed");
                    }
                }
                else
                {
                    Console.Error.WriteLine("no message integrity check");
                }
            }
            catch (PgpException e)
            {
                Console.Error.WriteLine(e);

                Exception underlyingException = e.InnerException;
                if (underlyingException != null)
                {
                    Console.Error.WriteLine(underlyingException.Message);
                    Console.Error.WriteLine(underlyingException.StackTrace);
                }
            }
        }