國密算法最好的應用場景應該是SSL/TLS通信,然而國密文檔中並沒有單獨規範SSL/TLS協議,我們能參考的只有《GM/T 0024-2014 SSL VPN 技術規範》。這份文檔並沒有像RFC那樣描述得很詳細,在實現上可能會存在很多不清楚的地方。很多時候,我們還要去翻看標準TLS 1.1的RFC4346。

本文主要總結國密SSL ECC_SM4_SM3密碼套件的實現需要注意的地方。

因爲國密SSL是以TLS 1.1標準爲藍本制定的,所以這裏主要總結國密SSL協議和標準的TLS協議之間的區別。

在SSL通信中,最重要的是通信握手,握手成功後,就可以通過加密通道進行通信,握手過程如下:

SSL握手

1. 協議版本

TLS協議定義有三個版本號,爲0x0301、0x0302、0x0303,分別對應TLS 1.0、1.1、1.2。國密SSL估計是擔心與未來的TLS版本號衝突,選擇了0x0101。這在實現上帶來一定的麻煩,因爲現有很多網絡庫會認爲這是一個無效的協議版本,需要一一將判斷修改過來。

國密SSL協議規範是TLS 1.1和TLS 1.2的混合體,大部分情況下參考TLS 1.1就可以了,少數地方又參考了TLS 1.2。在後面會指出哪些是參考了TLS 1.2的標準。

2. 加密算法

非對稱加密、對稱加密、摘要等算法都替換爲國密標準。在ECC_SM4_SM3套件中,非對稱加密算法爲SM2,對稱加密算法爲SM4,摘要算法爲SM3。

注意,PRF算法和TLS 1.2類似,而不是像TLS 1.1那樣,實現時需要注意:

國密PRF函數定義

TLS1.2下,PRF中所使用的哈希算法可根據選擇,比如SHA256,而GM SSL的算法固定爲SM3。

3. Certificate報文

國密規範規定發送證書時需要發送兩個證書:簽名證書和加密證書(雙證書體系)。關於雙證書請參考我之前的文章:

啥?雙證書?

與標準TLS報文格式一樣,但至少要包含兩個證書,簽名證書在前,加密證書在後。如果牽扯到證書鏈,問題就複雜了,而且協議這裏也沒有規定清楚。是簽名證書 + 證書鏈 + 加密證書,還是簽名證書 + 加密證書 + 證書鏈?在實現中發現 TASSL 採用的是前者,而 沃通測試網站 採用後者。在編碼時請注意,最好是兩者都兼容。

4. Certificate Verify

證書的驗籤流程和標準ECC證書的驗籤流程也不同,請參考《GMT 0003.2-2012 SM2橢圓曲線公鑰密碼算法第2部分:數字簽名算法》,在後面我會詳細寫一寫SM2的數字簽名算法。

5. 密鑰交換

實現時請參考RSA的密鑰交換,而不要參考橢圓曲線密鑰交換算法ECDH或ECDHE,這點需要注意。具體過程爲:

  1. 服務器發送SM2公鑰(在 加密證書 中)到客戶端。

  2. 客戶端生成Pre-Master Secret,用SM2公鑰加密後傳送給服務器。

  3. 服務器使用SM2私鑰解密,得到Pre-Master Secret,通過一定的處理得到Master Secret,再次處理得到會話密鑰,這個也是一個SM4對稱加密算法的密鑰。

  4. 客戶端使用同樣推導算法從Pre-Master Secret計算出Master Secret,然後再計算得到會話密鑰。因爲雙方都是從同樣的Pre-Master Secret值,使用同樣的密鑰派生算法計算出會話密鑰,所以最後會得到同樣的會話密鑰。

在握手協議的最後一步,雙方會互相發送Finished消息,其中就包含VerifyData,加密發送給對方。如果雙方的密鑰不同,校驗不會通過。

關於SM2加密Pre-Master Secret,請參考我之前的文章:

詳解國密SM2的加密和解密

Server Key Exchange消息中包含的數據如下:

Server Key Exchange消息

剛開始還不明白其中的

Opaque ASN.1Cert<1, 2^24-1>;

指的是什麼,該如何處理這個消息。後來才明白,對於ECC_SM4_SM3套件而言,會話密鑰其實主要由客戶端決定。對於客戶端而言,這個消息不處理也沒有問題,所以我把這個消息的處理略過了。開發服務器端的朋友可以補充一下,說說這個證書指的是哪個證書,我估計是加密證書。

6. Finished報文

Finish報文的內容也和TLS 1.1有差別,TLS 1.1的定義爲:

struct {
          opaque verify_data[12];
      } Finished;

      verify_data
          PRF(master_secret, finished_label, MD5(handshake_messages) +
          SHA-1(handshake_messages)) [0..11];

而國密SSL的Finished報文定義爲:

Finished消息

和TLS 1.2標準類似,但TLS 1.2可以使用標準的SHA1、SHA256、SHA384等進行hash運算,而國密SSL中,hash運算固定爲SM3。

小結

在實現國密SSL的過程中,碰到不少的坑,其實有些地方要是有人稍微點撥一下,也不至於摸索得那麼辛苦。現在我把總結出來的問題列出來,希望對大家有所幫助。

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

相關文章