陳琢,陳強(qiáng)
(成都衛(wèi)士通信息產(chǎn)業(yè)股份有限公司,成都610041)
隨著信息安全需求的發(fā)展,密碼技術(shù)已得到廣泛的使用,成為信息時(shí)代中不可獲缺的組成部分。同時(shí),為了提高密碼運(yùn)算的性能,提高密鑰等關(guān)鍵信息的安全性,例如USBKey、加密TF 卡、貼芯卡等專門的密碼設(shè)備應(yīng)運(yùn)而生,越來越多的系統(tǒng)使用這些密碼設(shè)備來分擔(dān)密碼運(yùn)算操作。為了給應(yīng)用開發(fā)人員便利地調(diào)用這些密碼設(shè)備,多個(gè)國際、國內(nèi)的加密API 標(biāo)準(zhǔn)隨即出現(xiàn)。這類標(biāo)準(zhǔn)為應(yīng)用隱藏了密碼設(shè)備的實(shí)現(xiàn)細(xì)節(jié),為應(yīng)用開發(fā)者提供統(tǒng)一的方式來使用不同的密碼設(shè)備,大大增強(qiáng)了應(yīng)用的可擴(kuò)展性[1]。其中,PKCS#11[2]和SKF[3]是使用較廣泛的兩種。
國家密碼管理局于2010 年首次發(fā)布《智能IC 卡及智能密碼鑰匙密碼應(yīng)用接口規(guī)范》,即SKF 接口標(biāo)準(zhǔn)。之后于2012 年11 月更新為GM/T0016-2012《智能密碼鑰匙密碼應(yīng)用接口規(guī)范》發(fā)布。目前很多國內(nèi)密碼設(shè)備廠商都為其產(chǎn)品提供了SKF 接口的開發(fā)包。隨著國密技術(shù)的發(fā)展,SKF 接口在加密模塊和軟件上的使用已越發(fā)廣泛。
在SKF 接口規(guī)范中,一個(gè)設(shè)備中存在一個(gè)設(shè)備認(rèn)證密鑰和多個(gè)應(yīng)用,應(yīng)用之間相互獨(dú)立,并具有各自的管理員PIN、用戶PIN 和權(quán)限。應(yīng)用邏輯結(jié)構(gòu)如圖1所示。
圖1 SKF設(shè)備的應(yīng)用邏輯結(jié)構(gòu)圖
以數(shù)據(jù)加密調(diào)用過程為例,SKF 接口使用的一個(gè)典型流程如下:
(1)枚舉設(shè)備:SKF_EnumDev
(2)連接設(shè)備:SKF_ConnectDev
(3)枚舉應(yīng)用:SKF_EnumApplication
(4)打開應(yīng)用:SKF_OpenApplication
(5)驗(yàn)證應(yīng)用PIN 碼:SKF_VerifyPIN(6)枚舉容器:SKF_EnumContainer
(7)打開容器:SKF_OpenContainer
(8)設(shè)置會(huì)話密鑰:SKF_SetSymmKey
(9)加密初始化:SKF_EncryptInit
(10)加密多個(gè)數(shù)據(jù)包:SKF_EncryptUpdate
(11)加密多個(gè)數(shù)據(jù)包結(jié)束:SKF_EncryptFinal
(12)關(guān)閉容器:SKF_CloseContainer
(13)關(guān)閉應(yīng)用:SKF_CloseApplication
(14)斷開設(shè)備連接:SKF_DisConnectDev
公鑰密碼標(biāo)準(zhǔn)PKCS(Public-Key Cryptography Standards)是RSA 實(shí)驗(yàn)室與本行業(yè)、學(xué)術(shù)界以及政府的代表一起合作推出的一套規(guī)范,它包含一系列規(guī)范,其中PKCS#11 是加密設(shè)備接口標(biāo)準(zhǔn)。該標(biāo)準(zhǔn)詳細(xì)規(guī)定了密碼令牌接口Cryptoki(Cryptographic Token Interface)的編程接口,現(xiàn)在由OASIS(Organization for the Advancement of Structured Information Standards,結(jié)構(gòu)化信息標(biāo)準(zhǔn)促進(jìn)組織)技術(shù)委員會(huì)管理,最新的正式版本是2.40。
PKCS#11 定義了會(huì)話(session)、槽(slot)、令牌(token)、對(duì)象(object)的概念,用于抽象密碼設(shè)備的使用過程。其中會(huì)話抽象應(yīng)用與設(shè)備的連接,槽抽象卡槽或讀卡器等安全設(shè)備,令牌抽象加密TF 卡等密碼設(shè)備,對(duì)象抽象在密碼操作中使用和產(chǎn)生各種數(shù)據(jù)結(jié)構(gòu)[4]。
使用PKCS#11 標(biāo)準(zhǔn)的密碼設(shè)備中,邏輯結(jié)構(gòu)如圖2 所示。
圖2 PKCS#11設(shè)備的邏輯結(jié)構(gòu)圖
以數(shù)據(jù)加密調(diào)用過程為例,Cryptoki 使用的一個(gè)典型流程如下:
(1)初始化接口庫:C_Initialize
(2)獲取密碼設(shè)備的槽位:C_GetSlotList
(3)選擇使用的槽位,創(chuàng)建會(huì)話:C_OpenSession
(4)登錄設(shè)備:C_Login
(5)查找已有的密鑰或生成新密鑰:
①查找初始化:C_FindObjectsInit
②進(jìn)行查找:C_FindObjects
③結(jié)束查找:C_FindObjectsFinal
④生成:C_GenerateKey 或C_GenerateKeyPair
(6)加密初始化:C_EncryptInit
(7)加密多個(gè)數(shù)據(jù)包:C_EncryptUpdate
(8)加密多個(gè)數(shù)據(jù)包結(jié)束:C_EncryptFinal
(9)退出登錄:C_Logout
(10)關(guān)閉會(huì)話:C_CloseSession
(11)退出庫調(diào)用狀態(tài):C_Finalize
SKF 和PKCS#11 均是密碼設(shè)備對(duì)外提供的接口標(biāo)準(zhǔn),為外部開發(fā)者調(diào)用密碼設(shè)備提供統(tǒng)一的、便利的途徑。本節(jié)對(duì)兩種接口的差異進(jìn)行比較。
在SKF 標(biāo)準(zhǔn)中,權(quán)限分為設(shè)備權(quán)限、用戶權(quán)限和管理員權(quán)限。在特定操作中(包括創(chuàng)建應(yīng)用、刪除應(yīng)用和修改設(shè)備認(rèn)證密鑰),需要設(shè)備權(quán)限。在SKF 設(shè)備中,每個(gè)應(yīng)用都有自己的PIN 碼(包括用戶PIN 碼和管理員PIN 碼),因此,各應(yīng)用可獨(dú)立地使用設(shè)備,獲取權(quán)限。
在PKCS#11 中,沒有設(shè)備權(quán)限,僅有用戶權(quán)限和管理員權(quán)限。設(shè)備上僅有一個(gè)用戶PIN 和一個(gè)管理員PIN。因此,當(dāng)一個(gè)應(yīng)用使用正確的PIN 碼登錄后,即通過了整個(gè)設(shè)備的權(quán)限認(rèn)證。
對(duì)于SKF 設(shè)備,應(yīng)用在開始使用時(shí)需要在設(shè)備中創(chuàng)建好相應(yīng)的應(yīng)用。因此,在正確枚舉出設(shè)備后,應(yīng)用可能涉及到的操作包括:設(shè)備認(rèn)證、創(chuàng)建應(yīng)用、打開應(yīng)用、驗(yàn)證PIN 碼(創(chuàng)建容器需要用戶權(quán)限)、創(chuàng)建容器。之后,可以此容器中進(jìn)行密鑰操作和調(diào)用密碼算法。
相對(duì)地,對(duì)于PKCS#11 設(shè)備,應(yīng)用在正確枚舉到設(shè)備后,需要的操作包括打開會(huì)話和登錄。之后即可進(jìn)密鑰操作和調(diào)用密碼算法。
SKF 接口通過應(yīng)用和容器來組織密鑰。在同一個(gè)設(shè)備中,可存在多個(gè)應(yīng)用,而每個(gè)應(yīng)用各自擁有若干個(gè)容器。一個(gè)容器可存放一對(duì)加密公私鑰對(duì)和一對(duì)簽名公私鑰對(duì),以及對(duì)應(yīng)的加密證書和簽名證書。在這些公私鑰對(duì)和證書生成或?qū)牒?,設(shè)備將它們保存起來,直到通過接口函數(shù)將它們刪除。在設(shè)備使用過程中產(chǎn)生的會(huì)話密鑰,僅在會(huì)話期間有效。當(dāng)會(huì)話關(guān)閉(如關(guān)閉容器)后,這些會(huì)話密鑰不會(huì)保存。因此,SKF 接口中,以非對(duì)稱密鑰和會(huì)話密鑰的操作為主,不支持對(duì)稱密鑰的存儲(chǔ)。其他數(shù)據(jù)可作為文件存儲(chǔ)于應(yīng)用中,通過SKF 的文件操作相關(guān)接口來進(jìn)行讀寫和控制。
相對(duì)地,PKCS#11 沒有應(yīng)用和容器的概念。它通過定義多種對(duì)象來組織密碼設(shè)備上的數(shù)據(jù),包括數(shù)據(jù)對(duì)象、證書對(duì)象和密鑰對(duì)象[5]。PKCS#11 為每類對(duì)象定義了豐富詳細(xì)的屬性參數(shù),使開發(fā)者可根據(jù)需求定義每個(gè)對(duì)象的屬性,例如是否在設(shè)備中保存、對(duì)象的標(biāo)識(shí)、是否可導(dǎo)出、是否可用于加解密、是否可用于打包其他密鑰,等等。在應(yīng)用調(diào)用PKCS#11 過程中,通過會(huì)話(session)來管理臨時(shí)產(chǎn)生的對(duì)象。在一個(gè)session中產(chǎn)生的臨時(shí)對(duì)象(session object),僅在此會(huì)話中可以使用。當(dāng)此session 關(guān)閉時(shí),這些對(duì)象都將消失。而保存于設(shè)備上的對(duì)象,所有應(yīng)用都有同樣的權(quán)限。
SKF 接口以支持國密算法為主,包括SM1、SM2、SM3、SM4,同時(shí)包括部分國際算法:RSA、SHA1 和SHA256。PKCS#11 支持多種國際算法,但可通過自定義機(jī)制進(jìn)行擴(kuò)展。
當(dāng)前,部分密碼設(shè)備提供PKCS#11 接口,不提供SKF 接口。在這種情況下,由于PKCS#11 接口更具普遍性,將PKCS#11 作為較低一層,可以實(shí)現(xiàn)SKF 接口,擴(kuò)大密碼設(shè)備的適用范圍。
基于PKCS#11 實(shí)現(xiàn)SKF 接口,主要需要解決上節(jié)中分析的SKF 與PKCS#11 的差異處。PKCS#11 對(duì)象中豐富的屬性,可用于建立與SKF 類似的應(yīng)用結(jié)構(gòu)。
在調(diào)用SKF 接口時(shí),為找到可用的設(shè)備,設(shè)備管理類的函數(shù)往往最先調(diào)用,主要包括枚舉設(shè)備、連接設(shè)備、斷開設(shè)備、獲取設(shè)備狀態(tài)等)。對(duì)應(yīng)到PKCS#11 接口中,可在此階段進(jìn)行庫的初始化,查找設(shè)備和獲取設(shè)備信息??赏ㄟ^C_Initialize、C_GetSlotList 等接口獲取。
由于SKF 和PKCS#11 中的權(quán)限管理不同,在這個(gè)階段中,除了進(jìn)行初始化,可完成PKCS#11 設(shè)備的登錄。此后不使用PKCS#11 設(shè)備上的PIN。例如,在連接設(shè)備時(shí),在已知密碼設(shè)備PKCS#11 的PIN 碼的情況下,調(diào)用PKCS#11 的登錄接口。
SKF 中設(shè)備認(rèn)證密鑰、應(yīng)用、容器及文件,由于在PKCS#11 無對(duì)應(yīng)的概念,可通過在PKCS#11 設(shè)備中存儲(chǔ)為對(duì)象來實(shí)現(xiàn)。對(duì)應(yīng)的層次及結(jié)構(gòu)關(guān)系,通過PKCS#11 對(duì)象可定義的豐富的屬性來實(shí)現(xiàn)。例如,可通過定義特定的CKA_APPLICATION 或CKA_LABEL來標(biāo)識(shí)出設(shè)備認(rèn)證密鑰,如下:
類似地,應(yīng)用、應(yīng)用PIN、容器、文件、證書均使用PKCS#11 數(shù)據(jù)對(duì)象存儲(chǔ),容器中的密鑰對(duì)應(yīng)使用PKCS#11 密鑰對(duì)象存儲(chǔ)??墒褂靡韵聦傩詠斫㈥P(guān)系。
●應(yīng)用和應(yīng)用PIN:在創(chuàng)建應(yīng)用時(shí),使用PKCS#11接口創(chuàng)建數(shù)據(jù)對(duì)象存儲(chǔ)??墒褂靡粋€(gè)對(duì)象。使用CKA_APPLICATION 標(biāo)識(shí)為SKF 相關(guān)對(duì)象。將接口中傳入的應(yīng)用名稱(szAppName)存入CKA_LABEL。PIN和PIN 的剩余可用次數(shù)及權(quán)限控制作為對(duì)象值寫入。
●容器:創(chuàng)建容器時(shí),使用PKCS#11 接口創(chuàng)建數(shù)據(jù)對(duì)象存儲(chǔ)。使用CKA_APPLICATION 標(biāo)識(shí)為某應(yīng)用的容器。CKA_LABEL 中存儲(chǔ)容器名稱。
●文件:創(chuàng)建文件時(shí),使用PKCS#11 接口創(chuàng)建數(shù)據(jù)對(duì)象存儲(chǔ)。使用CKA_APPLICATION 標(biāo)識(shí)為某應(yīng)用的文件。CKA_LABEL 中存儲(chǔ)文件名稱。其他內(nèi)容,包括文件大小,讀寫權(quán)限及文件內(nèi)容存入CKA_VALUE 中。
●證書:在證書導(dǎo)入時(shí),使用PKCS#11 接口創(chuàng)建數(shù)據(jù)對(duì)象存儲(chǔ)。使用CKA_APPLICATION 存儲(chǔ)應(yīng)用名、容器名及證書標(biāo)識(shí)。CKA_LABEL 中存儲(chǔ)證書類型(加密證書或簽名證書)。證書內(nèi)容存入CKA_VALUE中。
●密鑰:在密鑰產(chǎn)生時(shí),使用PKCS#11 接口創(chuàng)建密鑰對(duì)象存儲(chǔ)。使用CKA_ID 存儲(chǔ)應(yīng)用名、容器名、密鑰類型(加密密鑰或簽名密鑰)。
隨著密碼設(shè)備的廣泛使用,使用統(tǒng)一的、標(biāo)準(zhǔn)的密碼設(shè)備接口越來越關(guān)鍵。SKF 和PKCS#11 接口標(biāo)準(zhǔn)作為兩種主流接口,很好地解決了這個(gè)問題,增強(qiáng)了應(yīng)用程序的可移植性。本文對(duì)比分析了兩種標(biāo)準(zhǔn)的差異性,并提出基于PKCS#11 實(shí)現(xiàn)SKF 的一種方案,為使用SKF 和PKCS#11 的開發(fā)人員提供參考。