/*.......................................................................數位簽章開始*/ 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(); } }
/* * 文章 -> 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(); } }