夏 凡,文 剛,朱紅宏
(中國電子科技集團(tuán)公司第三十研究所,四川 成都 610041)
關(guān)鍵字:下一代加密技術(shù)接口;商密算法;SM2 證書;加密服務(wù)提供程序
目前,國內(nèi)主流企業(yè)所采用的密碼算法都是國際公開算法。國家密碼管理局早在2012年起就頒布了一系列的商密算法實現(xiàn)及應(yīng)用的規(guī)范文件。國內(nèi)的一些信息安全廠商和一些開源程序,例如,基于開放式安全套接層協(xié)議(Open Secure Sockets Layer,OpenSSL)實現(xiàn)的支持國密算法和標(biāo)準(zhǔn)的OpenSSL 分支(GmSSL)和天安版國密OpenSSL(TaSSL)也基于該系列規(guī)范實現(xiàn)了國密標(biāo)準(zhǔn)的對稱、非對稱、散列算法及接口規(guī)范。但基于該規(guī)范的實現(xiàn)與操作系統(tǒng)的實現(xiàn)有較大差異,目前,國密算法SM2 雖已被納入國際標(biāo)準(zhǔn),但在各大操作系統(tǒng)上依然沒有內(nèi)置該算法的實現(xiàn)。在實際使用時仍是由應(yīng)用程序開發(fā)人員使用各廠商提供的算法庫來實現(xiàn)對國密算法的使用。一些利用操作系統(tǒng)應(yīng)用程序接口(Application Programming Interface,API)實現(xiàn)密碼算法調(diào)用的應(yīng)用程序?qū)⒚媾R重新開發(fā)和定制的風(fēng)險。同時,證書信任是使用安全套接層(Secure Sockets Layer,SSL)的基本要求,各種瀏覽器、使用SSL 的客戶端在面對不信任的證書時都會彈出警告,甚至是直接斷開連接,但目前系統(tǒng)中并沒有實現(xiàn)SM2 證書的驗證,導(dǎo)致無法對某些安全性要求較強(qiáng)的業(yè)務(wù)進(jìn)行訪問。因此,本文通過研究微軟提出的新一代密碼應(yīng)用服務(wù)接口,實現(xiàn)國密算法在Windows 系統(tǒng)中的注冊及使用。在不修改原應(yīng)用程序的情況下,使應(yīng)用程序正確調(diào)用新注冊的國密算法以實現(xiàn)密碼服務(wù)功能,實現(xiàn)國密算法在Windows 操作系統(tǒng)中的無縫集成,完成國密證書在Windows 系統(tǒng)中的直接驗證及P12 格式的國密證書導(dǎo)入。
下一代加密技術(shù)接口(Cryptographic Next Generation API,CNG API)是微軟在Windows Vista 及之后的操作系統(tǒng)中實現(xiàn)的取代上一代CryptoAPI 的密碼服務(wù)接口。相對于上一代的CryptoAPI,它具備的優(yōu)勢如下:(1)更靈活的配置模型,支持更多的密鑰存儲配置、算法配置、隨機(jī)數(shù)發(fā)生器等;(2)完全兼容上一代CryptoAPI 接口;(3)支持內(nèi)核模式下的算法配置;(4)支持自定義的證書格式;(5)支持SSL/安全傳輸層(Transport Layer Security,TLS)的協(xié)議配置。在Windows Vista 及之后的操作系統(tǒng)中,默認(rèn)使用的密碼服務(wù)接口已經(jīng)替換為CNG API,CryptoAPI 也只是對CNG 的封裝調(diào)用。
CNG 允許密碼服務(wù)實現(xiàn)方以“Provider”的形式向系統(tǒng)添加密碼服務(wù)實現(xiàn),并向開發(fā)者提供軟件開發(fā)工具包(Software Development Kit,SDK),極大地方便了密碼服務(wù)提供商向系統(tǒng)注冊自己專有算法或者對密碼硬件的調(diào)用。CNG允許第三方密碼服務(wù)提供商提供的程序的主要功能如下文所述。
(1)密鑰存儲實現(xiàn)。第三方提供商以自己的方式實現(xiàn)密鑰的管理、產(chǎn)生、銷毀、使用等。例如,實現(xiàn)密鑰存儲可通過結(jié)合密碼硬件來實現(xiàn)私鑰的保存和使用,使私鑰既不出硬件,又能通過Windows 標(biāo)準(zhǔn)接口供應(yīng)用程序使用。密鑰存儲僅支持在用戶模式下注冊。
(2)密碼算法實現(xiàn)。第三方提供商可通過注冊密碼算法來實現(xiàn)對稱、摘要、非對稱加解密、簽名驗簽、隨機(jī)數(shù)發(fā)生器、密鑰衍生等功能。通過該方式,可以將一些專用的非公開算法方便地新增到系統(tǒng)中并由原生的Windows API使用。密碼算法可在用戶模式下和內(nèi)核模式下進(jìn)行注冊,在內(nèi)核模式下注冊后,驅(qū)動程序中也可以使用用戶自定義的密碼算法。
(3)密鑰衍生、協(xié)商實現(xiàn)。第三方提供商可注冊自己的密鑰衍生、密鑰協(xié)商實現(xiàn)類。
(4)SSL 協(xié)議實現(xiàn)。第三方提供商可注冊自己的協(xié)議實現(xiàn)類,實現(xiàn)TLS 協(xié)議交互過程中使用私有算法或者數(shù)據(jù)格式的認(rèn)證、密鑰協(xié)商、加密等功能。
在系統(tǒng)中注冊自定義算法時需要先注冊一個Provider,一個Provider 可包含多種算法實現(xiàn)的接口。Provider 及支持的接口關(guān)系如圖1所示。
由Provider 的結(jié)構(gòu)可以看出它涵蓋了密碼算法的所有功能,通過接口將算法注冊到系統(tǒng)后,即可實現(xiàn)算法接口的相關(guān)功能。本文通過將SM2 算法、SM3 算法注冊到Windows操作系統(tǒng)中,實現(xiàn)國密證書在Windows 中的識別、簽發(fā)、驗證。此外,還需要實現(xiàn)隨機(jī)數(shù)發(fā)生接口,以產(chǎn)生符合國密隨機(jī)數(shù)檢測規(guī)范的隨機(jī)數(shù)。
在數(shù)字證書中,以對象標(biāo)識符(Object Identifier,OID)來唯一標(biāo)識一種算法。密碼服務(wù)提供商通過Windows 標(biāo)準(zhǔn)接口CryptRegisterOIDInfo 來實現(xiàn)密碼算法OID 向操作系統(tǒng)的注冊,當(dāng)注冊算法時,在結(jié)構(gòu)CRYPT_OID_INFO 中填寫對應(yīng)的算法所屬的組(國密各算法及參數(shù)的OID 可在標(biāo)識規(guī)范中查詢)。根據(jù)實際需要,SM3 所屬組為BCRYPT_HASH_INTERFACE,SM2 作為公鑰算法時,其所屬的組為CRYPT_PUBKEY_ALG_OID_GROUP_ID;SM2 作為簽名算法時,其所屬的組為CRYPT_SIGN_ALG_OID_GROUP_ID。支持SM2 算法時,還需要根據(jù)用途填充OID 擴(kuò)展參數(shù),用作加密和驗簽時,則擴(kuò)展參數(shù)為3 個整型:第一個參數(shù)為公鑰用途,加密(CRYPT_OID_PUBKEY_ENCRYPT_ONLY_FLAG)、驗簽(CRYPT_OID_PUBKEY_SIGN_ONLY_FLAG)或兩者都支持;第二個參數(shù)為公鑰所屬算法的標(biāo)識;第三個參數(shù)為橢圓曲線算法(Elliptic Curve Cryptography,ECC)公鑰模長。用作簽名時,則擴(kuò)展參數(shù)為整型,值恒為CALG_OID_INFO_PARAMETERS。SM2 算法OID 注冊成功后,在Windows 下雙擊國密SM2 證書,可在證書詳細(xì)信息里面查看到公鑰、公鑰參數(shù)、簽名算法等值顯示為SM2、SM3 等注冊過的值[1]。注冊算法OID 前,系統(tǒng)則只能顯示出算法OID對應(yīng)的可識別文本信息,因算法的實現(xiàn)還需要通過Provider 的注冊后,才會被系統(tǒng)調(diào)用。在Windows 下未注冊O(shè)ID 和已注冊O(shè)ID 的國密證書顯示對比如圖2所示。
CNG 開發(fā)包提供了BCryptRegisterProvider 函數(shù)用于向系統(tǒng)中注冊Provider,本文討論的是應(yīng)用層的算法注冊,因此必須在BCryptRegisterProvider函數(shù)的PCRYPT_PRVIDER_REG 參數(shù)中填充SM2和SM3 算法,指定Provider 所處的動態(tài)庫文件名稱以及Provider 提供的算法類型。
Provider 注冊成功后,還需要向配置節(jié)點中添加各個算法的配置,CNG 開發(fā)包提供BCryptAddContextFunctionProvider 函數(shù)用于向Provider 中添加算法實現(xiàn)。
OID、Provider 及配置的算法在CNG 開發(fā)包中也提供了相應(yīng)的實現(xiàn),若操作系統(tǒng)中不再需要新注冊的算法,則調(diào)用函數(shù)CryptUnregisterOIDInfo 卸載已注冊的OID,調(diào)用函數(shù)BCryptUnregisterProvider卸載已注冊的Provider。
Provider 以動態(tài)庫的形式提供算法,為保證Windows 操作系統(tǒng)正確使用Provider 所提供的算法,動態(tài)庫必須實現(xiàn)導(dǎo)出函數(shù)來支持注冊到Provider 中的算法,導(dǎo)出的函數(shù)及含義如表1所示。
表1 Provider 導(dǎo)出函數(shù)及含義
根據(jù)微軟提供的CNG 開發(fā)包及其示例,在Provider 中實現(xiàn)了SM3 算法、SM2 算法及其相關(guān)函數(shù)接口。Windows 應(yīng)用程序調(diào)用的算法實際是由Provider 所提供的算法接口實現(xiàn)的。
2.3.1 SM3 的實現(xiàn)
Provider 中實現(xiàn)雜湊功能的函數(shù)接口GetHashInterface 原型如下:
在GetHashInterface 的實現(xiàn)代碼中以SM3 的實現(xiàn)函數(shù)填充返回的結(jié)構(gòu)體列表ppFunctionTable,其對應(yīng)的回調(diào)函數(shù)即可實現(xiàn)SM3 在系統(tǒng)中的注冊。完成SM3 算法注冊和相應(yīng)的功能后,可通過如下的示例代碼進(jìn)行驗證:
根據(jù)驗證程序的輸入和輸出結(jié)果,與國密SM3 密碼雜湊算法規(guī)范對比,兩者結(jié)果一致[2]。
2.3.2 SM2 的實現(xiàn)
Provider 中實現(xiàn)SM2 的簽名/驗簽、加密/解密以及公私鑰的導(dǎo)入和密鑰對產(chǎn)生等,需在CNG中分別對相應(yīng)結(jié)構(gòu)體進(jìn)行填充。簽名以結(jié)構(gòu)體BCRYPT_SIGNATURE_FUNCTION_TABLE 定義各個操作回調(diào),非對稱加密以結(jié)構(gòu)體BCRYPT_ASYMMETRIC_ENCRYPTION_FUNCTION_TABLE定義各個操作回調(diào)。Provider 中實現(xiàn)SM2 簽名驗簽的接口原型如下:
在以上GetSignatureInterface 的實現(xiàn)代碼中,以SM2 的實現(xiàn)函數(shù)填充返回的結(jié)構(gòu)體列表ppFunctionTable,其對應(yīng)的回調(diào)函數(shù)即可實現(xiàn)SM2算法的簽名、驗簽功能在系統(tǒng)中的注冊。然后應(yīng)用程序采用Windows 系統(tǒng)標(biāo)準(zhǔn)的CNG API 完成對SM2 算法的調(diào)用,調(diào)用流程與SM3 類似,細(xì)節(jié)可參考CNG 開發(fā)包提供的示例以及幫助文檔。
根據(jù)密碼行業(yè)標(biāo)準(zhǔn)GM/T 0009—2012《SM2 密碼算法使用規(guī)范》,使用SM2 的簽名功能需利用簽名方的用戶身份標(biāo)識和簽名方公鑰,通過SM3 運算得到Z 值[2],再將Z 值與待簽名消息通過SM3 計算哈希后簽名/驗簽[3]。該使用規(guī)范為SM2 特有,公開算法無此應(yīng)用方式。因此,應(yīng)用程序除通過擴(kuò)展BCRYPT_SIGNATURE_FUNCTION_TABLE 中的BCryptExportKeyFn 接口外,還需擴(kuò)展一個 BCRYPT_SM2Z_BLOB=L"SM2ZBLOB"的數(shù)據(jù)類型。通過調(diào)用BCryptExportKey,并指定數(shù)據(jù)類型為BCRYPT_SM2Z_BLOB,可計算出公鑰的Z 值,應(yīng)用程序?qū)⒋薢 值與待簽名數(shù)據(jù)計算哈希后再進(jìn)行簽名/驗簽。
將國密算法在操作系統(tǒng)中注冊完成后,以中國金融認(rèn)證中心(China Financial Certification Authority,CFCA)提供的SM2 測試證書鏈為例,驗證此國密SM2 證書能否通過驗證。
在Windows 系統(tǒng)中,證書都是通過 WinVerify TrustEx 接口函數(shù)進(jìn)行驗證的,在該接口里面內(nèi)置有證書解碼、證書完整性、有效性、證書鏈校驗等函數(shù)。基于SM2 算法的應(yīng)用規(guī)范[3],在對數(shù)據(jù)進(jìn)行簽名/驗簽時,先使用簽名公鑰與用戶標(biāo)識計算Z 值,然后與源數(shù)據(jù)合并計算SM3,最后對SM3 的結(jié)果進(jìn)行簽名/驗簽。
通過對Windows 系統(tǒng)中證書驗證的過程進(jìn)行分析[4],對證書完整性和有效性的驗證實際就是直接使用CryptDecodeObjectEx 接口對證書解碼,然后根據(jù)解碼后的數(shù)據(jù)計算哈希值,再將哈希值驗簽。該操作流程與SM2 的使用規(guī)范不符,無法通過SM2 的驗簽。為符合SM2 使用規(guī)范,需要在證書解碼后的數(shù)據(jù)前面添加簽發(fā)者Z 值。Windows系統(tǒng)提供 CryptInstallOIDFunctionAddress函數(shù)用于注冊自定義的編解碼函數(shù),通過該函數(shù)對X509_ASN_ENCODING 編碼類型注冊自定義編解碼。從簽名算法使用SM2 的證書獲取到簽發(fā)者的公鑰,并計算Z 值,再與系統(tǒng)自動編/解碼后的證書數(shù)據(jù)合并,以使簽名/驗簽的數(shù)據(jù)符合SM2 使用規(guī)范。
分別使用CFCA 提供的測試證書SM2 的根證書、下級證書為例,驗證未注冊國密算法的Windows 操作系統(tǒng)和已注冊國密算法的操作系統(tǒng),通過直接雙擊SM2 證書文件得到如圖3、圖4和圖5的結(jié)果。
通過圖片可直觀地看出:在系統(tǒng)中注冊國密算法后,操作系統(tǒng)自動實現(xiàn)了對國密算法證書的驗證。使用Windows 的標(biāo)準(zhǔn)接口 WinVerifyTrustEx驗證證書,同樣能得到證書驗證通過的結(jié)果。
本文通過對Windows 系統(tǒng)下新一代密碼接口的功能分析,完成了國密SM2、SM3 算法向系統(tǒng)中注冊,同時實現(xiàn)了對國密算法簽發(fā)的證書驗證,為進(jìn)一步實現(xiàn)國密SSL 協(xié)議[5]在Windows 系統(tǒng)中的集成奠定了基礎(chǔ),同時也為其他非公開算法向系統(tǒng)中注冊提供了一種實現(xiàn)思路。