1. 程式人生 > >簽名+驗籤(第三方)

簽名+驗籤(第三方)

紙質時代,當寫信,或者使用支票的時候,簽上自己的名字,就表示這是自己寫的,當別人拿到信的時候,如果認識筆跡,或者銀行拿到支票後,進行一系列驗證,驗證這個支票的真偽,前面的操作就是簽名,說明是自己寫的,後面的檢驗,就是驗籤,確認書寫者身份。

資訊時代,也有這方面的需要。

要確保資訊是某人傳送的,不讓別個知道里面的內容,而且中間沒有被修改,同時資訊要完整。(資訊保安三要素,有效性(Availability):資訊的使用者是合法的,保密性(Confidentiality):資訊在傳輸時不被洩露,有效性(Availability):資訊的使用者是合法的)

這個時候,首先想到的就是加密了。

加密有對稱加密,和非對稱加密 這兩種演算法

對稱加密,使用一個密碼來進行加密和解密,比如我約定規則,用明文(3)乘以4,在加1,這樣得到(3*4+1)密文13,另外一個人得到13後,用我們相同的約定,在反向推(13-1)/4=3,就得到我的明文,電視裡面密碼本就是這樣的。大家都知道怎麼解密的約定

非對稱加密,明文,用A加密,用B解密,加密和解密分別使用不同的規則。

目前大部分都是採用非對稱加密演算法

其中,公匙密碼就是非對稱加密的演算法的一個具體事列,公匙密碼又稱為非對稱密碼。擁有公匙密碼的人分別擁有加密密匙和解密密匙,通過加密密匙不能得到解密密匙,同時加密密匙是公開的。

李四擁有公匙密碼,他想獲得張三的銀行卡密碼66666,就把公匙給了張三,張三用公密加密後,通過網路傳給李四,其他人獲取到了這個密文後,沒有私密解不開,只有李四知道私密,可以解開,這樣,就保證了資訊的安全性,好像不能保證資訊傳送人就是張三,這個特性,其他人要是獲得了這個公匙,也能給李四發信息。

這個時候,我們進行逆運算,我用私匙加密,用公匙解密,因為只有私匙加密的東西,我才能用對應的公匙進行解開。同時我解密的時候,我就能確認傳送人了。(為什麼了?)

數字簽名(名詞):某種密碼運算生成一系列符號及程式碼組成電子密碼進行簽名,這個來表示是自己簽名

數字簽名(動詞):用私匙來加密,用公匙來解密,就是公共密碼的逆運算。

一般開發階段,我們都是使用到的是其他第三方給我們的東西進行加密和解密,一般會給我們這2個檔案

其中字尾為 .cer的通常存放公鑰,字尾為.pfx的通常存放私鑰(包含公匙和私匙,對方還會給你一個密碼,用來解開這個私匙的密碼)

NET中提供類 X509Certificate2,名稱空間 System.Security.Cryptography中,這個類實列化後就表示一個類

X509Certificate2 c3 = DataCertificate.GetCertificateFromPfxFile("d:\\mycert\\NT999.pfx", "000000");

string keyPublic3 = c3.PublicKey.Key.ToXmlString(false);  // 公鑰
 string keyPrivate3 = c3.PrivateKey.ToXmlString(true);  // 私鑰    

string check_value = HashAndSignString(uJson, keyPrivate3); // 加密,原文,私匙
 bool bt = VerifySigned(uJson, check_value, keyPublic3);//驗籤

       /// <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);
            }
        }

這就是一套流程。

生成簽名
一般來說,不直接對訊息進行簽名,而是對訊息的雜湊值進行簽名,步驟如下。
 1,   對訊息進行雜湊計算,得到雜湊值
  2,  利用私鑰對雜湊值進行加密,生成簽名
  3,  將簽名附加在訊息後面,一起傳送過去
驗證簽名
 1,  收到訊息後,提取訊息中的簽名
 2, 用公鑰對簽名進行解密,得到雜湊值1。
 3,  對訊息中的正文進行雜湊計算,得到雜湊值2。
 4,   比較雜湊值1和雜湊值2,如果相同,則驗證成功。

證書

證書實際上就是對公鑰進行數字簽名,它是對公鑰合法性提供證明的技術。
考慮這樣一種場景:我們對簽名進行驗證時,需要用到公鑰。如果公鑰也是偽造的,那怎麼辦?如果公鑰是假的,驗證數字簽名那就無從談起,根本不可能從數字簽名確定對方的合法性。
這時候證書就派上用場了。
證書一般包含:公鑰(記住證書中是帶有公鑰的),公鑰的數字簽名,公鑰擁有者的資訊
若證書驗證成功,這表示該公鑰是合法,可信的。
接下來又有問題了:驗證證書中的數字簽名需要另一個公鑰,那麼這個公鑰的合法性又該如何保證?該問題可以無限迴圈下去,豈不是到不了頭了?這已經是個社會學問題了。我們為什麼把錢存進銀行?因為我們相信銀行,它是一個可信的機構(雖然也有破產的風險)。跟銀行一樣,我們需要一個可信的機構來頒發證書和提供公鑰,只要是它提供的公鑰,我們就相信是合法的。

這種機構稱為認證機構(Certification Authority, CA)。CA就是能夠認定”公鑰確實屬於此人”,並能生成公鑰的數字簽名的組織或機構。CA有國際性組織和政府設立的組織,也有通過提供認證服務來盈利的組織。

如何生成證書?
    伺服器將公鑰A給CA(公鑰是伺服器的)
    CA用自己的私鑰B給公鑰A加密,生成數字簽名A
    CA把公鑰A,數字簽名A,附加一些伺服器資訊整合在一起,生成證書,發回給伺服器。


注:私鑰B是用於加密公鑰A的,私鑰B和公鑰A並不是配對的。

如何驗證證書?
客戶端得到證書
    客戶端得到證書的公鑰B(通過CA或其它途徑)
    客戶端用公鑰B對證書中的數字簽名解密,得到雜湊值
    客戶端對公鑰進行雜湊值計算
    兩個雜湊值對比,如果相同,則證書合法。


注:公鑰B和上述的私鑰B是配對的,分別用於對證書的驗證(解密)和生成(加密)。
證書作廢


當用戶私鑰丟失、被盜時,認證機構需要對證書進行作廢(revoke)。要作廢證書,認證機構需要製作一張證書作廢清單(Certificate Revocation List),簡稱CRL


假設我們有Bob的證書,該證書有合法的認證機構簽名,而且在有效期內,但僅憑這些還不能說明該證書一定有效,還需要查詢認證機構最新的CRL,並確認該證書是否有效。
使用場景


下面用兩個使用場景來幫助大家理解證書的作用。


客戶端在傳送或接收訊息之前,要驗證伺服器的合法性(這個伺服器是真實的伺服器,還是偽造者,我們不知道)


場景1


    伺服器生成公鑰和私鑰密碼對
    伺服器把公鑰給CA。CA生成證書,傳送給客戶端
    客戶端驗證證書,取得公鑰:此刻證明公鑰是合法的
    客戶端用公鑰加密訊息,傳送給伺服器
    伺服器用私鑰解密訊息(訊息加密傳送,具有保密性)


場景2


    伺服器生成公鑰和私鑰密碼對
    伺服器生成訊息,用私鑰對訊息進行數字簽名
    伺服器把公鑰給CA。CA生成證書
    伺服器將訊息,數字簽名,證書一起傳送給客戶端
    客戶端驗證證書,取得公鑰:此刻證明公鑰是合法的

    客戶端用公鑰驗證數字簽名,檢查訊息的完整性和伺服器的合法性

後續再慢慢寫

轉載:https://www.jianshu.com/p/9db57e761255

轉載:https://segmentfault.com/a/1190000004461428

新手淺談證書加解密、簽名驗籤

參考:http://blog.csdn.net/weixin_33602978/article/details/71599672

  ASP.net 使用證書認證

參考:http://blog.csdn.net/wsxqaz/article/details/5389883

參考:https://www.cnblogs.com/atongmyuxiaowanzi/p/5329558.html