密碼引擎
密碼引擎API的主要標(biāo)準(zhǔn)和規(guī)范包括:
1 微軟的Crypto API
2 RAS公司的PKCS#11標(biāo)準(zhǔn)
3 中國商用密碼標(biāo)準(zhǔn):GMT 0016-2012 智能密碼鑰匙密碼應(yīng)用接口規(guī)范,GMT 0018-2012密碼設(shè)備應(yīng)用接口規(guī)范等
任務(wù)詳情
- 查找各種標(biāo)準(zhǔn)的原始文檔,研究學(xué)習(xí)(至少包含Crypto API,PKCS#11,GMT 0016-2012,GMT 0018-2012)
- 總結(jié)這些API在編程中的使用方式
- 列出這些API包含的函數(shù),進(jìn)行分類,并總結(jié)它們的異同
- 以龍脈GM3000Key為例,寫出調(diào)用不同接口的代碼(Crypto API,PKCS#11,SKF接口),把運(yùn)行截圖加入博客,并提供代碼鏈接
0.研究學(xué)習(xí)原始文檔
CryptoAPI
https://learn.microsoft.com/en-us/windows/win32/seccrypto/cryptography-portal
https://learn.microsoft.com/en-us/windows/win32/seccrypto/cryptography-portal
https://learn.microsoft.com/en-us/windows/win32/seccrypto/cryptographic-provider-types
https://learn.microsoft.com/en-us/windows/win32/seccrypto/microsoft-cryptographic-service-providers
PKCS#11
PKCS#11 v2.20
GM/T 0016-2012 智能密碼鑰匙密碼應(yīng)用接口規(guī)范
GM/T 0018-2012 密碼設(shè)備應(yīng)用接口規(guī)范
密碼行業(yè)標(biāo)準(zhǔn)列表
1.總結(jié)這些API在編程中的使用方式
CryptoAPI
微軟的CryptoAPI是PKI推薦使用的加密 API。其功能是為應(yīng)用程序開發(fā)者提供在Win32環(huán)境下使用加密、驗(yàn)證等安全服務(wù)時(shí)的標(biāo)準(zhǔn)加密接口。CryptoAPI處于應(yīng)用程序和CSP(cryptographic service provider)之間。

Cryptoki 為一個(gè)或多個(gè)密碼設(shè)備提供一個(gè)接口,這些設(shè)備通過大量的槽在系統(tǒng)中運(yùn)行。每個(gè)對(duì)應(yīng)于一個(gè)物理閱讀器或另一個(gè)設(shè)備接口的槽可包含一個(gè)令牌。當(dāng)一臺(tái)密碼設(shè)備存在于閱讀器中,一個(gè)令牌就存在于該槽中。當(dāng)然,由于Cryptoki提供槽和令牌的邏輯視圖,所以可能有其它的物理譯碼。多個(gè)槽可能共享一個(gè)閱讀器。問題在于一個(gè)系統(tǒng)有相當(dāng)多的槽,應(yīng)用程序能連接到這些槽的其中任何一個(gè)或全部槽的令牌上。
Cryptoki的令牌邏輯視圖是一個(gè)能存儲(chǔ)對(duì)象和能執(zhí)行密碼函數(shù)的設(shè)備。Cryptoki定義如下三個(gè)對(duì)象:數(shù)據(jù)、證書和密鑰。數(shù)據(jù)對(duì)象由應(yīng)用程序定義。一個(gè)證書對(duì)象存儲(chǔ)一個(gè)證書。一個(gè)密鑰對(duì)象存儲(chǔ)一個(gè)密碼密鑰。密鑰可以是一個(gè)公共密鑰、一個(gè)私鑰或是一個(gè)保密密鑰,每個(gè)種類的密鑰在專用機(jī)制中使用其的輔助型。令牌的這種邏輯視圖如下圖所示:

SKF
針對(duì)支持國密算法USB KEY設(shè)備的應(yīng)用,我國頒布一個(gè)行業(yè)標(biāo)準(zhǔn)《智能密碼鑰匙應(yīng)用接口規(guī)范》(GM/T0016-2012),市面上銷售的國密算法的USB KEY設(shè)備必須支持這個(gè)接口規(guī)范。因此,只要根據(jù)這個(gè)規(guī)范開發(fā)的應(yīng)用程序,就可以兼容使用不同廠家及品牌的USB KEY產(chǎn)品。由于此規(guī)范中函數(shù)名稱都以SKF開頭,所以我們一般把按照此規(guī)范提供的設(shè)備開發(fā)接口庫叫做SKF庫或SKF接口。
智能密碼鑰匙密碼應(yīng)用接口位于智能密碼鑰匙應(yīng)用程序與設(shè)備之間,如下圖所示

一個(gè)設(shè)備中存在設(shè)備認(rèn)證密鑰和多個(gè)應(yīng)用,應(yīng)用之間相互獨(dú)立。設(shè)備的邏輯結(jié)構(gòu)如下圖所示

應(yīng)用由管理員PIN,用戶PIN、文件和容器組成,可以存在多個(gè)文件和多個(gè)容器。每個(gè)應(yīng)用維護(hù)各自的與管理員PIN和用戶PIN相關(guān)的權(quán)限狀態(tài)。
一個(gè)應(yīng)用的邏輯結(jié)構(gòu)如下圖所示

容器中存放加密密鑰對(duì)、簽名密鑰對(duì)和會(huì)話密鑰。其中加密密鑰對(duì)用于保護(hù)會(huì)話密鑰,簽名密鑰對(duì)用于數(shù)字簽名和驗(yàn)證,會(huì)話密鑰用于數(shù)據(jù)加解密和MAC運(yùn)算。容器中也可以存放與加密密鑰對(duì)對(duì)應(yīng)的加密數(shù)字證書和與簽名密鑰對(duì)對(duì)應(yīng)的簽名數(shù)字證書。其中,簽名密鑰對(duì)由內(nèi)部產(chǎn)生,加密密鑰對(duì)由外部產(chǎn)生并安全導(dǎo)入,會(huì)話密鑰可由內(nèi)部產(chǎn)生或者由外部產(chǎn)生并安全導(dǎo)入。
2.列出這些API包含的函數(shù),進(jìn)行分類,并總結(jié)它們的異同
CryptoAPI
密碼服務(wù)提供者CSP函數(shù)
CryptoAPI的密碼服務(wù)提供者函數(shù)主要包括6個(gè)函數(shù)。連接或斷開CSP函數(shù)CryptAcquireContext、CryptReleaseContext,枚舉CSP函數(shù)CryptEnumProviders,獲得或設(shè)置默認(rèn)CSP函數(shù)CryptGetDefaultProvider、CryptSetProvider,獲取或設(shè)置CSP參數(shù)函數(shù)CryptGetProvParam、CryptSetProvParam。
連接CSP函數(shù) CryptAcquireContext
函數(shù)功能:連接CSP,獲得指定CSP的密鑰容器的句柄。
枚舉CSP函數(shù) CryptEnumProviders
函數(shù)功能:枚舉計(jì)算機(jī)上的所有CSP。此函數(shù)可以得到第一個(gè)或下一個(gè)可用的CSP。如果循環(huán)調(diào)用可以得到計(jì)算機(jī)上所有可用的CSP。
獲得默認(rèn)CSP函數(shù) CryptGetDefaultProvider
函數(shù)功能:獲得系統(tǒng)默認(rèn)的CSP。
設(shè)置默認(rèn)CSP函數(shù) CryptSetProvider
函數(shù)功能:設(shè)置系統(tǒng)默認(rèn)的CSP。
獲得CSP參數(shù)屬性函數(shù) CryptGetProvParam
函數(shù)功能:獲得CSP各種參數(shù)屬性。
設(shè)置CSP參數(shù)函數(shù) CryptSetProvParam
函數(shù)功能:設(shè)置CSP各種參數(shù)屬性。
斷開CSP函數(shù) CryptReleaseContext
函數(shù)功能:斷開CSP,釋放CSP句柄,和 CryptAcquireContext相對(duì)應(yīng)。
示例枚舉CSP并獲得默認(rèn)CSP的參數(shù)處理過程如下圖所示

密鑰的產(chǎn)生與交換函數(shù)
CryptoAPI密鑰產(chǎn)生和交換函數(shù)主要有生成密鑰函數(shù) CryptGenKey、派生密鑰函數(shù)CryptDeriveKey、銷毀密鑰函數(shù)CryptDestoryKey、復(fù)制密鑰函數(shù)CryptDuplicateKey、導(dǎo)出密鑰函數(shù)CryptExportKey、導(dǎo)入密鑰函數(shù)CryptImportKey、獲得密鑰參數(shù)函數(shù)CryptGetKeyParam、設(shè)置密鑰參數(shù)函數(shù)CryptSetKeyParam、產(chǎn)生隨機(jī)函數(shù) CryptGenRandom。
生成函數(shù) CryptGenKey
函數(shù)功能:產(chǎn)生一個(gè)隨機(jī)的對(duì)稱或非對(duì)稱算法的密鑰。
派生密鑰函數(shù) CryptDeriveKey
函數(shù)功能:根據(jù)基礎(chǔ)數(shù)據(jù)派生一對(duì)稱密鑰(會(huì)話密鑰)。
銷毀密鑰函數(shù) CryptDestroyKey
函數(shù)功能:銷毀密鑰。
復(fù)制密鑰函數(shù) CryptDuplicateKey
函數(shù)功能:復(fù)制一個(gè)密鑰。產(chǎn)生一個(gè)密鑰的拷貝,包括其狀態(tài)。
導(dǎo)出密鑰函數(shù) CryptExportKey
函數(shù)功能:從CSP導(dǎo)出密鑰或密鑰對(duì)。
導(dǎo)入密鑰函數(shù) CryptlmportKey
函數(shù)功能:把BLOB數(shù)據(jù)導(dǎo)入的CSP。該函數(shù)可以導(dǎo)入會(huì)話密鑰、公鑰、或者公/私鑰對(duì)。
獲得密鑰參數(shù)函數(shù) CryptGetKeyParam
函數(shù)功能:獲得key句柄的各項(xiàng)參數(shù)。
獲得密鑰參數(shù)函數(shù) CryptSetKeyParam
函數(shù)功能:設(shè)置key句柄的各項(xiàng)參數(shù)。
獲得密鑰參數(shù)函數(shù) CryptGenRandom
函數(shù)功能:生成隨機(jī)數(shù)。
示例密鑰產(chǎn)生和交換實(shí)例處理過程如下圖所示

數(shù)據(jù)的加密與解密函數(shù)
CryptoAPI利用CryptEncrypt函數(shù)實(shí)現(xiàn)數(shù)據(jù)加密,利用CryptDecrypt實(shí)現(xiàn)數(shù)據(jù)解密。調(diào)用這2個(gè)函數(shù)前必須指定一個(gè)密鑰,這個(gè)密鑰可以由CryptGenKey、CryptDeriveKey或CryptImportKey產(chǎn)生。也可用CryptSetKeyParam函數(shù)指定額外的加密參數(shù)。
數(shù)據(jù)加密函數(shù) CryptEncrypt
函數(shù)功能:使用hKey指定的密鑰和算法加密數(shù)據(jù)。
數(shù)據(jù)解密函數(shù) CryptDecrypt
函數(shù)功能:使用hKey指定的密鑰和算法對(duì)加密數(shù)據(jù)解密。
示例數(shù)據(jù)加密處理過程如下圖所示

示例數(shù)據(jù)解密處理過程如下圖所示

哈希和數(shù)字簽名函數(shù)
CryptoAPI提供的哈希和數(shù)字簽名函數(shù)包括創(chuàng)建哈希函數(shù)CryptCreateHash、銷毀哈希CryptDestroyHash、復(fù)制哈希函數(shù)CryptDuplicateHash、獲得哈希參數(shù)函數(shù)CryptGetHashParam,設(shè)置哈希參數(shù)函數(shù)CryptSetHashParam、哈希會(huì)話密鑰函數(shù) CryptHashSessionKey、哈希數(shù)據(jù)函數(shù)CryptHashData、對(duì)哈希簽名函數(shù)CryptSignHash和對(duì)哈希驗(yàn)證簽名函數(shù)CryptVerifySignature。
創(chuàng)建哈希函數(shù) CryptCreateHash
函數(shù)功能:創(chuàng)建哈希。
銷毀哈希 CryptDestroyHash
函數(shù)功能:銷毀哈希對(duì)象。
復(fù)制哈希函數(shù) CryptDuplicateHash
函數(shù)功能:復(fù)制一個(gè)哈希對(duì)象。
獲得哈希參數(shù)函數(shù) CryptGetHashParam
函數(shù)功能:獲得哈希對(duì)象的參數(shù)。
設(shè)置哈希參數(shù)函數(shù) CryptSetHashParam
函數(shù)功能:設(shè)置哈希對(duì)象的參數(shù)。
哈希會(huì)話密鑰函數(shù) CryptHashSessionKey
函數(shù)功能:對(duì)一個(gè)會(huì)話密鑰進(jìn)行哈希,把它加到指定的哈希對(duì)象中。
哈希數(shù)據(jù)函數(shù) CryptHashData
函數(shù)功能:對(duì)數(shù)據(jù)進(jìn)行哈希操作,此函數(shù)可以反復(fù)調(diào)用。
對(duì)哈希簽名函數(shù) CryptSignHash
函數(shù)功能:對(duì)哈希對(duì)象進(jìn)行簽名。
對(duì)哈希驗(yàn)證簽名函數(shù) CryptVerifySignature
函數(shù)功能:驗(yàn)證哈希簽名。
示例對(duì)數(shù)據(jù)簽名和驗(yàn)證的流程如下圖所示

證書和證書庫函數(shù)
CryptoAPI證書和證書庫函數(shù)主要包括打開證書庫函數(shù)CertOpenStore、關(guān)閉證書庫函數(shù)CertCloseStore、從證書庫枚舉證書函數(shù)CertEnumCertificatesInStore、從證書庫查找證書函數(shù)CertFindCertificateInStore、創(chuàng)建證書句柄函數(shù) CertCreateCertificateContext、釋放證書句柄函數(shù)CertFreeCertificateContext、獲得證書句柄屬性函數(shù)CertGetCertificateContextProperty、設(shè)置證書句柄屬性函數(shù)CertSetCertificateContextProperty和獲得證書主題名稱函數(shù)CertGetNameString。
打開證書庫函數(shù) CertOpenStore
函數(shù)功能:根據(jù)證書庫類型,打開證書庫。
關(guān)閉證書庫函數(shù) CertCloseStore
函數(shù)功能:關(guān)閉證書庫。
從證書庫枚舉證書函數(shù) CertEnumCertificateslnStore
函數(shù)功能:枚舉證書庫中的證書。該函數(shù)通過循環(huán)調(diào)用,可以枚舉證書庫內(nèi)的全部證書,上一次的返回,是下一次的pPrevCertContext,直到返回值為NULL。
從證書庫查找證書函數(shù) CertFindCertificatelnStore
函數(shù)功能:從證書庫中查找指定的證書。
創(chuàng)建證書句柄函數(shù) CertCreateCertificateContext
函數(shù)功能:由證書數(shù)據(jù)創(chuàng)建證書句柄。
釋放證書句柄函數(shù) CertFreeCertificateContext
函數(shù)功能:釋放證書句柄。
獲得證書句柄屬性函數(shù) CertGetCertificateContextProperty
函數(shù)功能:獲得證書句柄屬性。
設(shè)置證書句柄屬性函數(shù) CertSetCertificateContextProperty
函數(shù)功能:設(shè)置證書句柄屬性。
獲得證書主題名稱函數(shù) CertGetNameString
函數(shù)功能:從證書中獲得主題或頒發(fā)者的名稱。
示例枚舉證書庫并輸出其屬性的處理流程如下圖所示

SKF
設(shè)備管理函數(shù)

訪問控制函數(shù)


應(yīng)用管理函數(shù)

文件管理函數(shù)

容器管理函數(shù)

得到國密證書
根據(jù)國密標(biāo)準(zhǔn),一種設(shè)備類型可以有多個(gè)設(shè)備(Device),每一個(gè)設(shè)備內(nèi)可以有多個(gè)應(yīng)用(Application),每一個(gè)應(yīng)用里可以有多個(gè)容器(Container),每個(gè)容器里可以有一對(duì)證書(Certificate):簽名證書和加密證書。
數(shù)字簽名
在數(shù)字簽名時(shí),要指定簽名所使用的證書。通過遍歷本機(jī)上的證書,與簽名用的證書進(jìn)行對(duì)比,定位到簽名證書在USBKEY中的位置,得到設(shè)備、應(yīng)用和容器的句柄,然后使用證書的私鑰進(jìn)行簽名。遍歷對(duì)比的過程可參見上一節(jié)的內(nèi)容。另外,由于數(shù)字簽名會(huì)用到私鑰,因此這里需要驗(yàn)證口令。
驗(yàn)證簽名
1.SKF_CreateContainer(HAPPLICATION hApplication, LPSTR szContainerName, HCONTAINER *phContainer)
調(diào)用此方法創(chuàng)建一個(gè)臨時(shí)容器。hApplication為容器所在的應(yīng)用句柄;szContainerName是ASCII字符串,表示所建立容器的名稱,最大長(zhǎng)度不能超過64字節(jié);phContainer是返回所建立容器的容器句柄。
2.SKF_ImportCertificate(HCONTAINER hContainer, BOOL bSignFlag, BYTE* pbCert, ULONG ulCertLen);
將簽名用的證書導(dǎo)入到容器中。hContainer為容器句柄,即用上一方法創(chuàng)建的臨時(shí)容器;bSignFlag為證書類型,TRUE表示簽名證書,F(xiàn)ALSE表示加密證書,這里選TRUE;pbCert,是證書數(shù)據(jù);ulCertLen為證書數(shù)據(jù)長(zhǎng)度;
3.SKF_ExportPublicKey(HCONTAINER hContainer, BOOL bSignFlag, BYTE* pbBlob, ULONG* pulBlobLen);
導(dǎo)出公鑰。
4.SKF_DigestInit(DEVHANDLE hDev, ULONG ulAlgID, ECCPUBLICKEYBLOB *pPubKey, unsigned char *pucID, ULONG ulIDLen, HANDLE *phHash);
雜湊初始化。
5.SKF_Digest(HANDLE hHash, BYTE *pbData, ULONG ulDataLen, BYTE *pbHashData, ULONG *pulHashLen);
雜湊運(yùn)算。
6.SKF_ECCVerify(DEVHANDLE hDev , ECCPUBLICKEYBLOB* pECCPubKeyBlob, BYTE *pbData, ULONG ulDataLen, PECCSIGNATUREBLOB pSignature);
進(jìn)行簽名驗(yàn)證。hDev是設(shè)備句柄;pECCPubKeyBlob是公鑰數(shù)據(jù)結(jié)構(gòu),即第3步得到的公鑰; pbData為待驗(yàn)證簽名的數(shù)據(jù);ulDataLen是待驗(yàn)證簽名數(shù)據(jù)長(zhǎng)度;pbSignature待驗(yàn)證的簽名值。
7.SKF_DeleteContainer(HAPPLICATION hApplication, LPSTR szContainerName);
刪除臨時(shí)容器。hApplication為容器所在的應(yīng)用句柄;szContainerName為容器名稱。
3.以龍脈GM3000Key為例,寫出調(diào)用不同接口的代碼(Crypto API,PKCS#11,SKF接口),把運(yùn)行截圖加入博客,并提供代碼鏈接
CryptoAPI
需要使用x64編譯
EncryptDecryptFile
EncrypteFile

DecryptFile


原始C文件和加密后二進(jìn)制文件和解密出來的文件

EnumCerts
枚舉證書

Sign_Verify

PKCS#11
需要使用win32編譯
EnumObj

這里登入顯示需要輸入PIN碼,但其實(shí)輸入Key的密鑰就行了。
exportcert

這里登入顯示需要輸入PIN碼,但其實(shí)輸入Key的密鑰就行了。
public key object


代碼鏈接
https://gitee.com/xieyi23333/information_security_xieyi/tree/master/GM3000Key
GetUSBInfos

可以看到正確顯示了key的信息
PKCSDemo

RSA Sign

posted on 2023-04-04 10:43 20201321周慧琳 閱讀(120) 評(píng)論(0) 收藏 舉報(bào)
浙公網(wǎng)安備 33010602011771號(hào)