解析X509证书
原文:http://hi.baidu.com/lidhcn/item/5476d292a0710eda1a49df60
1.從磁盤上的證書文件中讀取證書數(shù)據(jù)
unsigned char* pbX509Data; // 證書數(shù)據(jù)?unsigned long ulX509DataLen; // 證書數(shù)據(jù)長(zhǎng)度?
2.獲取CertContext?
PCCERT_CONTEXT pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, pbX509Data, ulX509DataLen);?
3.獲取證書信息
pCertContext->pCertInfo->dwVersion; // 證書版本號(hào)?
CRYPT_INTEGER_BLOB snBlob = pCertContext->pCertInfo->SerialNumber; // 證書SN?
CERT_NAME_BLOB issuerBlob = pCertContext->pCertInfo->Issuer; // 證書頒發(fā)者?
CERT_NAME_BLOB subjectBlob = pCertContext->pCertInfo->Subject; // 證書主題?
// 證書有效起始日期?
SYSTEMTIME sysTime;?
memset(&sysTime, 0, sizeof(sysTime));?
FileTimeToSystemTime(&pCertContext->pCertInfo->NotBefore, &sysTime);?
char szTime[128] = {0};?
sprintf_s(szTime, 128, "%d年%d月%d日%d:%d:%d", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);?
// 證書有效終止日期?
memset(&sysTime, 0, sizeof(sysTime));?
FileTimeToSystemTime(&pCertContext->pCertInfo->NotAfter, &sysTime);?
memset(szTime, 0, sizeof(szTime));?
sprintf_s(szTime, 128, "%d年%d月%d日%d:%d:%d", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);?
4.創(chuàng)建臨時(shí)密鑰容器
HCRYPTPROV hTmpProv = NULL;?
CryptAcquireContext(&hTmpProv, "My_Temporary_Container", NULL, PROV_RSA_AES, 0); // NULL表示使用系統(tǒng)默認(rèn)CSP?
5.向容器中導(dǎo)入公鑰,獲取公鑰句柄
HCRYPTKEY hKey = NULL;?
CERT_PUBLIC_KEY_INFO certPubKeyInfo = pCertContext->pCertInfo->SubjectPublicKeyInfo;?
CryptImportPublicKeyInfo(hTmpProv, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, &certPubKeyInfo, &hKey);?
6.導(dǎo)出公鑰(最好采用二次調(diào)用方式)
unsigned char* pBuf = NULL;?
unsigned long ulBufLen = 0;?
CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pBuf, &ulBufLen);?
pBuf = new unsigned char[ulBufLen];?
memset(pBuf, 0, ulBufLen);?
CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pBuf, &ulBufLen);?
7.獲取公鑰信息
unsigned char* p = pBuf + sizeof(PUBLICKEYSTRUC);?
(*(RSAPUBKEY*)p).bitlen; // 公鑰模長(zhǎng)(以bit為單位)?
(*(RSAPUBKEY*)p).pubexp; // 公鑰的e(注意字節(jié)順序)?
p += sizeof(RSAPUBKEY); // 公鑰的n(注意字節(jié)順序)?
8.清理工作
delete[] pBuf;?
pBuf = NULL;?
CryptDestroyKey(hKey);?
CryptReleaseContext(hTmpProv, 0);?
CertFreeCertificateContext(pCertContext);
總結(jié)