詳解國密SM2的數字簽名

在《解讀國密非對稱加密算法SM2》一文中,我講到過非對稱加密算法的用途之一就是數字簽名。本文就來聊一聊國密SM2的數字簽名算法。

數字簽名(又稱公鑰數字簽名)是隻有信息的發送者才能產生的別人無法僞造的一段數字串,這段數字串同時也是對信息的發送者發送信息真實性的一個有效證明。它是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領域的技術來實現的,用於鑑別數字信息的方法。一套數字簽名通常定義兩種互補的運算,一個用於簽名,另一個用於驗證。數字簽名是非對稱密鑰加密技術與數字摘要技術的應用。

數字簽名的流程

不論採取何種算法進行數字簽名,其流程都是差不多的,先說一說簽名流程:

簽名流程
  1. 發送者對消息計算摘要值。

  2. 發送者用私鑰對摘要值進行簽名得到簽名值。

  3. 發送者將原始消息和簽名值一同發給接收者。

再來說一說簽名驗證流程:

驗籤流程
  1. 接收者接收到消息後,拆分出消息和消息簽名值A。

  2. 接收者使用公鑰對消息進行運算得到摘要值B。

  3. 接收者對摘要值B和簽名值A進行比較,如果相同表示簽名驗證成功,否則就是驗證失敗。

請注意,上面的流程並不是對消息本身簽名,而是對消息的摘要值進行簽名,這是因爲非對稱加密算法通常比較慢,而且校驗摘要值可以保證消息沒有篡改。不論消息有多長,在某種摘要算法下,其摘要值的長度是固定的,對其進行簽名速度較快,也比較容易處理。

ECDSA簽名算法

目前主流的簽名算法有RSA數字簽名算法和DSA數字簽名算法。RSA數字簽名算法和RSA加密算法相似,不同的是,RSA加密算法是公鑰加密,私鑰解密,而RSA簽名算法是私鑰簽名,公鑰驗證簽名。DSA(Digital Signature Algorithm)數字簽名算法生成簽名、驗證簽名的機制和RSA數字簽名算法是一樣的。這裏不詳細展開,這些算法都比較成熟,有豐富的資料可參考,一般網絡庫也都有實現,有興趣的朋友自行搜索。

DSA算法結合ECC,稱爲ECDSA數字簽名算法。在前面的文章我說過,SM2實際上就是一種橢圓曲線(EC)密碼算法,所以這裏先詳細說說標準的ECDSA算法,然後再說說SM2數字簽名算法和ECDSA算法有哪些差別。

在《解讀國密非對稱加密算法SM2》一文中,我們已經知道,對於橢圓曲線密碼算法而言,最重要的是選擇一條命名曲線,包括幾個重要的參數:p、a、b、G(x,y)和n。而在ECDSA算法中,有三個參數很重要:

  • 命名曲線。

  • G,橢圓曲線的基點。

  • n,相當於G基點的打點次數。

在《詳解國密SM2的加密和解密》一文中,我們已經談過密鑰對的生成,這裏再重複一下:

  • 選擇一個隨機數作爲私鑰d, 1 < d < n -1

  • 基於私鑰生成公鑰,P(x, y) = d * G(x, y)

簽名生成:

下面的步驟中,M是消息,HASH(M)是對消息進行摘要運算。d爲私鑰,P爲公鑰。

  1. 生成一個隨機數k,1 < k < n -1

  2. 計算(x, y) = k * G

  3. 計算r = x mod n

  4. 計算s = (k**-1 * (HASH(M) + d*r)) mod n

  5. 得到簽名值(r, s)。

詳細過程請參考 ANSI X9.62 這份文檔(收費文檔),上面步驟略去了幾個運算值結果檢查,另外需要注意上面的運算是大數運算,請不要使用普通的算術運算。

驗證簽名:

  1. 將簽名轉化爲兩個數r和s,假如r和s小於1或者大於n-1,驗證直接失敗

  2. 計算c = (s)**-1 mod n

  3. 計算u1 = ((HASH(M)) * c) mod n

  4. 計算u2 = ((r) * c) mod n

  5. 計算(x, y) = u1 * G + u2 * P

  6. 如果r == x mod n,則簽名驗證成功,否則失敗

如果從頭實現上面的運算,確實不太容易,因爲ECDSA已經相當成熟,所以現在的網絡庫基本上都有實現。在現有的ECDSA算法基礎上修改,增加對SM2簽名算法的支持,相對比較容易,下面就說說SM2數字簽名算法。

SM2數字簽名算法

SM2數字簽名算法在《GMT 0003.2-2012 SM2橢圓曲線公鑰密碼算法第2部分:數字簽名算法》這份文檔中有詳細的描述。其中籤名的流程爲:

SM2簽名流程

從中我們可以看到和標準ECDSA的流程有幾點不同:

  1. 對消息的處理不同,國密簽名算法對消息進行了處理,然後才計算摘要。其中 ZA 的計算涉及到命名曲線參數的a、b、G、P

  2. A5、A6的運算和ECDSA的第3、4步不一樣

  3. 國密簽名過程中,如果出現不合法的值,需要返回到A3步,重新生成隨機數,直到值合法。

雖然SM2數字簽名算法的計算步驟有所差別,但ECDSA中的基本運算,比如大數的加減乘除、曲線的乘積、取模運算都可以重用,所以實現起來也不是很困難。

驗證簽名的流程:

如果實現了簽名流程,驗證簽名的流程也比較容易實現,主要是需要關注其中的公式,注意一些細節。

在開發SM2數字簽名算法時,我們可以參考附錄A中的示例,保證每個步驟的數據能對上,這樣最終的結果就不會出錯。

小結

本文主要闡述了SM2數字簽名算法,它並不神祕,如果參考着ECDSA來實現,從技術角度講並不是很複雜。雖然數字簽名算法可以用來防抵賴、防篡改,但還有一個問題沒解決,客戶端如何確保接收到的服務器公鑰不是僞造的?舉個例子,假如某個服務器聲稱自己是騰訊公司的服務器,發給你公鑰,你用該公鑰進行數字簽名驗證,可以通過,但實際上這個服務器是一個山寨版。這個時候必須要藉助數字證書,才能解決這樣的安全問題。關於數字證書,後面再談。

如果大家有什麼問題,歡迎交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章