標籤:
一、版本號碼
結構體CERT_INFO中的欄位dwVersion即為認證版本,可以直接通過下面的代碼獲得:
DWORD dwCertVer = m_pCertContext->pCertInfo->dwVersion;
版本值的定義如下:
#define CERT_V1 0 #define CERT_V2 1 #define CERT_V3 2
也就是說,V1的值為0;V3的值為2,目前絕大多是認證都是V3版本。
二、序號
序號對應結構體CERT_INFO中的欄位SerialNumber,不過該欄位為ASN.1編碼的大數對象,需要解碼才能轉化為我們平時看到的十六進位序號。擷取序號的函數如下:
ULONG CCSPCertificate::get_SN(LPSTR lptcSN,ULONG *pulLen){CHAR scSN[512] = {0};if (!m_pCertContext){return CERT_ERR_INVILIDCALL;}if (!pulLen){return CERT_ERR_INVALIDPARAM;}PCRYPT_INTEGER_BLOB pSn = &(m_pCertContext->pCertInfo->SerialNumber);for (int n = (int)(pSn->cbData - 1); n >= 0; n--){CHAR szHex[5] = {0};sprintf_s(szHex, "%02X", (pSn->pbData)[n]);strcat_s(scSN, 512, szHex);}if (!lptcSN){*pulLen = strlen(scSN) + 1;return CERT_ERR_OK;}if (*pulLen <= strlen(scSN) + 1){return CERT_ERR_BUFFER_TOO_SMALL;}strcpy_s(lptcSN, *pulLen, scSN);*pulLen = strlen(scSN);return CERT_ERR_OK;}
三、公開金鑰演算法(認證演算法)
認證中的公開金鑰演算法,需要通過CERT_INFO中欄位SubjectPublicKeyInfo來擷取。具體函數如下:
ULONG CCSPCertificate::get_KeyType(ULONG* pulType){if (!m_pCertContext){return CERT_ERR_INVILIDCALL;}if (!pulType){return CERT_ERR_INVALIDPARAM;}PCERT_PUBLIC_KEY_INFO pPubKey = &(m_pCertContext->pCertInfo->SubjectPublicKeyInfo);if (pPubKey){if (_stricmp(pPubKey->Algorithm.pszObjId, szOID_RSA_RSA) == 0){*pulType = CERT_KEY_ALG_RSA;}else if (_stricmp(pPubKey->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY) == 0){*pulType = CERT_KEY_ALG_ECC;}else {*pulType = 0;return CERT_ERR_ALG_UNKNOWN;}}else{return GetLastError();}return CERT_ERR_OK;}
四、認證用途
認證從用途來分,分為“簽署憑證”和“加密認證”兩大類。“簽署憑證”的公開金鑰用來驗證簽名,而“加密認證”的公開金鑰則用來加密資料。我們需要通過調用函數CertGetIntendedKeyUsage()來擷取認證的用途,具體函數實現如下:
ULONG CCSPCertificate::get_KeyUsage(ULONG* lpUsage){BYTE btUsage[2] = {0};if (!m_pCertContext){return CERT_ERR_INVILIDCALL;}if (!lpUsage){return CERT_ERR_INVALIDPARAM;}if (CertGetIntendedKeyUsage(GLOBAL_ENCODING_TYPE, m_pCertContext->pCertInfo, btUsage, 2)){if (btUsage[0] & CERT_DIGITAL_SIGNATURE_KEY_USAGE){*lpUsage = CERT_USAGE_SIGN;}else if (btUsage[0] & CERT_DATA_ENCIPHERMENT_KEY_USAGE){*lpUsage = CERT_USAGE_EXCH;}else{*lpUsage = 0;return CERT_ERR_USAGE_UNKNOWN;}}else{return GetLastError();}return CERT_ERR_OK;}
五、簽名演算法
認證的簽名演算法,是指認證用來簽名時使用的演算法(包含HASH演算法)。簽名演算法用結構體CERT_INFO中SignatureAlgorithm欄位來表示,可以通過SignatureAlgorithm的子欄位pszObjId返回簽名演算法的Oid,這樣對比Oid就可以知道簽名演算法的具體含義了。pszObjId常見得定義如下:
#define CERT_SIGNATURE_ALG_RSA_RSA"1.2.840.113549.1.1.1" //RSA直接簽名#define CERT_SIGNATURE_ALG_MD2RSA"1.2.840.113549.1.1.2" //MD2作Hash、然後RSA簽名#define CERT_SIGNATURE_ALG_MD4RSA"1.2.840.113549.1.1.3" //MD4作Hash、然後RSA簽名#define CERT_SIGNATURE_ALG_MD5RSA"1.2.840.113549.1.1.4" //MD5作Hash、然後RSA簽名#define CERT_SIGNATURE_ALG_SHA1RSA"1.2.840.113549.1.1.5" //SHA1作Hash、然後RSA簽名#define CERT_SIGNATURE_ALG_SM3SM2"1.2.156.10197.1.501" //SM3作Hash、然後SM2簽名
以上為http://blog.csdn.net/yyfzy/article/details/46790043內容
接下來是我的實現
有需要源碼的留下郵箱
使用windows crypt API解析X509認證