實驗一-密碼引擎-3-加密API研究
任務詳情
密碼引擎API的主要標準和規範包括:
- 微軟的Crypto API
- RAS公司的PKCS#11標準
- 中國商用密碼標準:GMT 0016-2012 智慧密碼鑰匙密碼應用介面規範,GMT 0018-2012密碼裝置應用介面規範等
研究以上API介面,總結他們的異同,並以龍脈GM3000Key為例,寫出呼叫不同介面的程式碼,提交部落格連結和程式碼連結。
內容:
0. 查詢各種標準的原始文件,研究學習
- 微軟的Crypto API
- CryptoAPI 系統體系結構
- Web Crypto API
- PKCS#11
- PKCS#11標準文件
- 中國商用密碼標準
- GMT 0016-2012 智慧密碼鑰匙密碼應用介面規範
- GMT 0018-2012 密碼裝置應用介面規範
1. 總結這些API在程式設計中的使用方式
- 微軟的Crypto API:
- 提供了一組函式用於在 Windows 平臺上執行各種加密和安全操作,包括資料加密、數字簽名、證書管理等。開發者可以使用這些函式來實現檔案加密、數字簽名、證書管理等功能,而不需要了解底層加密演算法的細節。
- PKCS#11:
- 定義了一組平臺無關的 API,用於與密碼令牌(如硬體安全模組和智慧卡)進行互動。提供了對加密物件(如RSA金鑰、X.509證書、對稱金鑰等)的建立、使用、修改和刪除的功能。
- 中國商用密碼標準:
- GMT 0016-2012:規定了基於PKI密碼體制的智慧密碼鑰匙密碼應用介面,包括函式、資料型別、引數定義等。
- GMT 0018-2012:規定了服務類密碼裝置的應用介面標準,適用於密碼裝置的研製、使用和應用開發。
2. 列出這些API包含的函式,並進行分類
微軟的Crypto API:
- 加密函式:
- CryptEncrypt, CryptDecrypt
- 數字簽名函式:
- CryptSignMessage, CryptVerifyMessage
- 證書管理函式:
- CertCreateCertificateContext, CertFreeCertificateContext
PKCS#11:
- 初始化函式:
- C_Initialize, C_Finalize
- 物件管理函式:
- C_CreateObject, C_DestroyObject
- 加密函式:
- C_Encrypt, C_Decrypt
中國商用密碼標準:
GMT 0016-2012:
- 金鑰管理函式:
- InitKeyHandle, GenerateKey
- 加密函式:
- EncryptData, DecryptData
GMT 0018-2012:
- 裝置初始化函式:
- DeviceInit, DeviceFinal
- 物件管理函式:
- CreateObject, DestroyObject
程式碼示例
Crypto API
// 主函式
void main(void)
// 加密檔案
BOOL EncryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword)
// 解密檔案
BOOL DecryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword)
// 簽名檔案
BOOL SignFile(PCHAR szSource, PCHAR szDestination)
// 驗證簽名
BOOL VerifyFile(PCHAR szSource, PCHAR szDestination)
// 錯誤處理
void HandleError(char *s)
加密檔案
開啟原始檔: hSource = fopen(szSource,“rb”)
取得金鑰容器(CSP)控制代碼: CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,0)
建立會話金鑰:
CryptCreateHash(hCryptProv,CALG_MD5, 0, 0, &hHash)
CryptHashData(hHash, (BYTE *)szPassword, strlen(szPassword), 0)
CryptDeriveKey(hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey)
CryptDestroyHash(hHash)
加密資料檔案:
CryptEncrypt(hKey, 0, feof(hSource), 0, pbBuffer, &dwCount, dwBufferLen)
清理工作:
free(pbBuffer)
CryptDestroyKey(hKey)
CryptDestroyHash(hHash)
CryptReleaseContext(hCryptProv, 0)
解密檔案
開啟加密檔案(同上)
取得金鑰容器(CSP)控制代碼(同上)
建立會話金鑰(同上)
解密資料檔案:
CryptDecrypt(hKey, 0, feof(hSource), 0, pbBuffer, &dwCount)
清理工作: (同上)
簽名檔案
開啟原始檔(同上)
取得金鑰容器(CSP)控制代碼(同上)
取得簽名用的金鑰控制代碼(非對稱RSA金鑰)
CryptGetUserKey(hCryptProv, AT_SIGNATURE, &hKey)
匯出簽名用金鑰對的公鑰
CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)
計算資料檔案的Hash值
CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)
CryptHashData(hHash, pbBuffer, dwCount, 0)
對資料檔案的Hash值進行簽名
CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen)
清理工作: (同上)
驗證簽名
開啟檔案(同上)
取得金鑰容器(CSP)句
(2)PKCS#11
根據機制標記,可以分為幾類:
CKF_ENCRYPT:加密類
CKF_DECRYPT:解密類
CKF_DIGEST:摘要類
CKF_SIGN:簽名類
CKF_SIGN_RECOVER:可恢復簽名類
CKF_VERIFY:驗證類
CKF_VERIFY_RECOVER:可恢復驗證類
CKF_GENERATE:金鑰產生
CKF_GENERATE_KEY_PAIR:金鑰對產生
CKF_WRAP:金鑰封裝
CKF_UNWRAP:金鑰解封
CKF_DERIVE:金鑰派生
(3)GMT 0016-2012
(4)GMT 0018-2012
下列檔案對於本檔案的應用是必不可少的。凡是注日期的引用檔案,僅注日期的版本適用於本檔案,凡是不注日期的引用檔案,其最新版本(包括所有的修單)適用於本檔案,
- GM/T0006 密碼應用標識規範
- GM/T0009 SM2密碼演算法使用規範
3. 以龍脈GM3000Key為例,寫出呼叫不同介面的程式碼
# 使用微軟的Crypto API
import win32crypt
def encrypt_data(data, key):
encrypted_data = win32crypt.CryptEncrypt(data, key)
return encrypted_data
def decrypt_data(data, key):
decrypted_data = win32crypt.CryptDecrypt(data, key)
return decrypted_data
# 使用PKCS#11
from pkcs11 import CryptoToken
def encrypt_data(data, token):
encrypted_data = token.encrypt(data)
return encrypted_data
def decrypt_data(data, token):
decrypted_data = token.decrypt(data)
return decrypted_data
# 使用GMT 0016-2012
from gmt0016 import SmartKey
def encrypt_data(data, key_handle):
encrypted_data = SmartKey.encrypt_data(data, key_handle)
return encrypted_data
def decrypt_data(data, key_handle):
decrypted_data = SmartKey.decrypt_data(data, key_handle)
return decrypted_data
# 使用GMT 0018-2012
from gmt0018 import ServiceKeyDevice
def encrypt_data(data, device_handle):
encrypted_data = ServiceKeyDevice.encrypt(data, device_handle)
return encrypted_data
def decrypt_data(data, device_handle):
decrypted_data = ServiceKeyDevice.decrypt(data, device_handle)
return decrypted_data