在日常工作中,有很多文件需要領導審閱、簽名和蓋章,由於公司業務開展,跨地域、跨國業務也日益普遍,領導簽名蓋章變得很麻煩,開始的時候人們通過郵寄、傳真等方式來解決,但是耗費時間、人力、物力。在網絡化日益深入的今天,需要領導審批、簽字蓋章的東西越來越多,時間也越來越緊迫,數字簽名的出現,很好了解決了這一問題。推動了互聯網及跨國集團的發展。 數字簽名 1、概念 數字簽名基於哈希算法和公鑰加密算法,對明文報文先用哈希算法計算摘要,然後用私鑰對摘要進行加密,得到的值就是原文的數字簽名。 數字簽名(又稱公鑰數字簽名、電子簽章)是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領域的技術實現,用於鑒別數字信息的方法。 一套數字簽名通常定義兩種互補的運算,一個用於簽名,另一個用於驗證。 可以由下圖表示電子簽名的用處: 2、工作原理 流程圖如下: 數字簽名的使用一般涉及以下幾個步驟,我們通過安全電子郵件為案例進行介紹 (1)發件人生成或取得獨一無二的加密密碼組,包括私鑰和公鑰。 (2)發件人書寫電子郵件 (3)發件人用安全的摘要算法獲取電子郵件的信息摘要 (4)發件人再使用私鑰對信息摘要進行加密,即可得到數字簽名。 (5)發件人將數字簽名附在信息之後. (6)發件人將數字簽名和信息(加密或未加密)發送給電子收件人. (7)收件人使用發件人的公共密碼(公鑰)確認發件人的電子簽名,即將發件人的數字簽名通過公鑰進行解密,得到信息摘要 (8)收件人使用同樣安全的摘要算法,獲取信息(加密或未加密)的"信息摘要". (9)收件人比較兩個信息摘要.假如兩者相同,則收件人可以確信信息在簽發後並未作任何改變 (10) 收件人從證明機構處獲得認證證書(或者是通過信息發件人獲得),這一證書用以確認發件人發出信息上的數字簽名的真實性.證明機構在數字簽名系統中是一個典型的受委托管理證明業務的第三方.該證書包含發件人的公共密碼和姓名(以及其他可能的附加信息),由證明機構在其上進行數字簽名. 其中,第(1)~(6)是數字簽名的制作過程,(7)~(10)是數字簽名的核實過程 3、主要作用 1、防冒充,因為私鑰只有簽名者自己知道,其他人不能偽造出正確的簽名 2、可鑒別身份,接收方用發送方的公開公鑰對報文簽名進行解密運算後,和原文進行匹配 3、防篡改,明文和簽名值一起發送,相互驗證,防止數據被篡改 4、防抵賴,簽名值可以鑒別身份,帶簽名的數據裡包含的信息簽名者是不能抵賴的 4、應用 現在典型的應用如:網上銀行、電子商務、電子政務、網絡通信等 其中一個最重要的應用場景為:數字的證書,後續有具體文章對其進行詳細介紹。 5、通過RSA實現數字簽名 數字簽名 復制代碼 /// <summary> /// 數字簽名 /// </summary> /// <param name="plaintext">原文</param> /// <param name="privateKey">私鑰</param> /// <returns>簽名</returns> public static string HashAndSignString(string plaintext, string privateKey) { UnicodeEncoding ByteConverter = new UnicodeEncoding(); byte[] dataToEncrypt = ByteConverter.GetBytes(plaintext); using (RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider()) { RSAalg.FromXmlString(privateKey); //使用SHA1進行摘要算法,生成簽名 byte[] encryptedData = RSAalg.SignData(dataToEncrypt, new SHA1CryptoServiceProvider()); return Convert.ToBase64String(encryptedData); } } 復制代碼 簽名認證: 復制代碼 /// <summary> /// 驗證簽名 /// </summary> /// <param name="plaintext">原文</param> /// <param name="SignedData">簽名</param> /// <param name="publicKey">公鑰</param> /// <returns></returns> public static bool VerifySigned(string plaintext, string SignedData, string publicKey) { using (RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider()) { RSAalg.FromXmlString(publicKey); UnicodeEncoding ByteConverter = new UnicodeEncoding(); byte[] dataToVerifyBytes = ByteConverter.GetBytes(plaintext); byte[] signedDataBytes = Convert.FromBase64String(SignedData); return RSAalg.VerifyData(dataToVerifyBytes, new SHA1CryptoServiceProvider(), signedDataBytes); } } 復制代碼 測試用例: 復制代碼 public static void TestSign() { string originalData = "文章不錯,這是我的簽名:奧巴馬!"; Console.WriteLine("簽名數為:{0}",originalData); KeyValuePair<string,string> keyPair = Encrypter.CreateRSAKey(); string privateKey = keyPair.Value; string publicKey = keyPair.Key; //1、生成簽名,通過摘要算法 string signedData = Encrypter.HashAndSignString(originalData, privateKey); Console.WriteLine("數字簽名:{0}",signedData); //2、驗證簽名 bool verify = Encrypter.VerifySigned(originalData, signedData,publicKey); Console.WriteLine("簽名驗證結果:{0}",verify); } 復制代碼