密碼引擎-3-加密API研究

李宜时發表於2024-04-10

任務內容

研究以上API介面,總結他們的異同,並以龍脈GM3000Key為例,寫出呼叫不同介面的程式碼,提交部落格連結和程式碼連結。
內容:
0 查詢各種標準的原始文件,研究學習(至少包含Crypto API,PKCS#11,GMT 0016-2012,GMT 0018-2012)(5分)
1 總結這些API在程式設計中的使用方式(5分)
2 列出這些API包含的函式,進行分類,並總結它們的異同(10分)
3 以龍脈GM3000Key為例,寫出呼叫不同介面的程式碼(Crypto API,PKCS#11,SKF介面),把執行截圖加入部落格,並提供程式碼連結(10分)
以下是我的學習連結:https://learn.microsoft.com/zh-cn/windows/win32/seccrypto/cryptoapi-system-architecture#base-cryptographic-functions
https://www.jianshu.com/p/b5a80fe0e901
https://www.doc88.com/p-6911351376514.html
https://v1.cecdn.yun300.cn/150001_2107145025/GMT0018-2012密碼裝置應用介面規範(1).pdf
https://blog.csdn.net/liuhuiyi/article/details/7778123
https://www.w3.org/TR/WebCryptoAPI/

任務詳情

1.API在程式設計中的使用方式

  1. 瞭解API文件:在使用任何API之前,首先需要閱讀其文件。文件通常包含了如何配置和使用API的詳細指南,包括如何認證、API支援的請求型別、傳遞引數的方式、響應的資料格式等關鍵資訊。

  2. 配置認證資訊:大多數API,特別是商業API,要求使用者進行身份認證以使用其服務。這通常涉及到生成API金鑰、設定OAuth令牌等。根據API的要求,將這些認證資訊妥善配置到你的請求中。

  3. 構造請求:根據API文件構造HTTP請求。這包括選擇正確的HTTP方法(GET、POST、PUT等)、設定請求頭、構造請求體(對於POST和PUT請求)以及設定任何必要的查詢引數。

  4. 處理響應:傳送請求後,你將收到API的響應。根據API文件,解析響應體中的資料。這可能涉及到處理JSON或XML格式的資料,提取你需要的資訊。

  5. 錯誤處理和除錯:在使用API的過程中,可能會遇到各種錯誤,如網路問題、認證失敗、請求引數錯誤等。根據API返回的錯誤程式碼和資訊,進行相應的錯誤處理和除錯。有時,你可能需要記錄請求和響應的詳細資訊,以便進一步分析問題。

2、基本加密函式

CSP是真正實行加密的獨立模組,他既可以由軟體實現也可以由硬體實現。但是他必須符合CryptoAPI介面的規範。
每個CSP都有一個名字和一個型別。每個CSP的名字是唯一的,這樣便於CryptoAPI找到對應的CSP。目前已經有9種CSP型別,並且還在增長。下表列出出它們支援的金鑰交換演算法、簽名演算法、對稱加密演算法和Hash演算法。

CSP型別 交換演算法 簽名演算法 對稱加密演算法 Hash演算法
PROV_RSA_FULL RSA RSA RC2、RC4 MD5、SHA
PROV_RSA_SIG none RSA none MD5、SHA
PROV_RSA_SCHANNEL RSA RSA RC4、DES、Triple DES MD5、SHA
PROV_DSS DSS none DSS MD5、SHA
PROV_DSS_DH DH DSS CYLINK_MEK MD5、SHA
PROV_DH_SCHANNEL DH DSS DES、Triple DES MD5、SHA
PROV_FORTEZZA KEA DSS Skipjack SHA
PROV_MS_EXCHANGE RSA RSA CAST MD5
PROV_SSL RSA RSA Varies Varies

裝置的應用結構


基本資料型別

通用的介面
















3. 以龍脈GM3000Key為例,寫出呼叫不同介面的程式碼(Crypto API,PKCS#11,SKF介面),把執行截圖加入部落格





(三)PKCS#11

1.龍脈密碼鑰匙驅動例項工具等\mToken-GM3000\pkcs11\windows\samples\PKCStest\PKCStest.sln

(1)DES


(2)DES3



(3)Rc2


(4)RC4


(5)RSA


(6)AES

龍脈密碼鑰匙驅動例項工具等\mToken-GM3000\pkcs11\windows\samples\GetUSBInfos\getusbinfos.sln

相關程式碼:

Ⅰ.Crypto API#

Copy

HCRYPTPROV hCryptProv;
HCRYPTHASH hCryptHash;
HCRYPTKEY hCryptKey;


CPAcquireContext(
    hCryptProv, NULL,
    MS_DEF_PROV,
    PROV_RSA_FULL,
    CRYPT_VERIFYCONTEXT
)//為應用程式建立一個上下文
    
CPCreateHash(
    hCryptProv,
    CALG_MD5,
    0,
    0,
    &hCryptHash
) //為應用程式建立一個上下文
    
static char szHash[]=”PISAHASHDATA”; //原始字串
DWORD dwLen=strlen(szHash);
CPHashData(hCryptHash, (BYTE*)szHash, dwLen, 0);//雜湊輸入的資料
CPDeriveKey(hCryptProv, CALG_RC2, hCryptHash, 0, &hCryptKey);//從一個資料雜湊中生成一個會話金鑰,它保證生成的金鑰互不相同

static char szEntry[]= “PISA2002”;
DWORD dwLenIn = strlen(szEntry);
DWORD dwLenOut=dwLenIn;
CPEncrypt(hCryptKey, 0, TRUE, 0, (BYTE*)szEntry, &dwLenOut, dwLenIn);//用來加密明文
CPDecrypt(hCryptKey, 0, TRUE, 0,(BYTE*)szEntry,&dwLenOut);//用來解密先前被加密的資料
CPDestroyKey(hCryptKey);//釋放一個金鑰控制代碼,釋放後,控制代碼將無效,金鑰將無法再被訪問
CPDestroyHash(hCryptHash);//刪除一個雜湊物件控制代碼
CPReleaseContext(hCryptProv, NULL);//釋放CPAcquireContext.建立的上下文

Ⅱ.PKCS#11

CK_SESSION_HANDLE hSession;
CK_MECHANISM digestMechanism;
CK_ULONG ulStateLen;
CK_BYTE data1[] = {0x01, 0x03, 0x05, 0x07};
CK_BYTE data2[] = {0x02, 0x04, 0x08};
CK_BYTE data3[] = {0x10, 0x0F, 0x0E, 0x0D, 0x0C};
CK_BYTE pDigest[20];
CK_ULONG ulDigestLen;
CK_RV rv;

/* Initialize hash operation */
rv = C_DigestInit(hSession, &digestMechanism);//初始化訊息雜湊計算操作,指定計算訊息雜湊的演算法
assert(rv == CKR_OK);

/* Start hashing */
rv = C_DigestUpdate(hSession, data1, sizeof(data1));//對多個分組的訊息進行雜湊計算
assert(rv == CKR_OK);//返回成功或者失敗

/* Find out how big the state might be */
rv = C_GetOperationState(hSession, NULL_PTR, &ulStateLen);//獲取裝置是否存在的狀態
assert(rv == CKR_OK);//返回成功或者失敗

/* Allocate some memory and then get the state */
pState = (CK_BYTE_PTR) malloc(ulStateLen);
rv = C_GetOperationState(hSession, pState, &ulStateLen);//獲取裝置是否存在的狀態

/* Continue hashing */
rv = C_DigestUpdate(hSession, data2, sizeof(data2));//對多個分組的訊息進行雜湊計算
assert(rv == CKR_OK);//返回成功或者失敗

/* Restore state.  No key handles needed */
rv = C_SetOperationState(hSession, pState, ulStateLen, 0, 0);
assert(rv == CKR_OK);//返回成功或者失敗

/* Continue hashing from where we saved state */
rv = C_DigestUpdate(hSession, data3, sizeof(data3));//對多個分組的訊息進行雜湊計算
assert(rv == CKR_OK);//返回成功或者失敗

/* Conclude hashing operation */
ulDigestLen = sizeof(pDigest);
rv = C_DigestFinal(hSession, pDigest, &ulDigestLen);
if (rv == CKR_OK) {
  /* pDigest[] now contains the hash of 0x01030507100F0E0D0C */
}//返回成功或者失敗

相關文章