来源:https://blog.csdn.net/dlfer11/article/details/50345035 标签:Windows,crypto API,示例 收藏:株野 作者: dlfer11 日期:2015年12月17日 17:54:59 MS CryptoAPI Samples // examCrypt.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" // Link with the Crypt32.lib file. #pragma comment(lib, "Crypt32") #pragma comment(lib, "comsuppw.lib") #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) //============================================================================================ // 暂停 void pause() { _tprintf(L"\nPress ENTER key to continue \n"); getchar(); } // 错误报告 void CancelByError(TCHAR* str) { _tprintf(L"\nFAULT:\n"); _tprintf(L"An error occurred in running the program. \n"); _tprintf(L"%s", str); _tprintf(L"Error number %x. \n", GetLastError()); _tprintf(L"Program terminating. \n"); pause(); exit(1); } // 字节反序 void reverse(BYTE* data, int nLen) { for(int ii=0; ii < nLen/2; ii++) { BYTE c = data[ii]; data[ii] = data[nLen -ii -1]; data[nLen -ii -1] = c; } } // 输出文件 void writeFile(const char* sFileName, BYTE* data, DWORD nSize) { FILE* fp = fopen(sFileName, "wb"); if(fp == NULL) { printf("Can not open output file '%s'! \n", sFileName); return; } if(fwrite(data, 1, nSize, fp) != nSize) { fclose(fp); printf("Write to file '%s' failed! \n", sFileName); return; } fclose(fp); printf("Write %d bytes to file '%s'! \n", nSize, sFileName); } // 读取文件(data = NULL for get file size ONLY) void readFile(const char* sFileName, BYTE* data, DWORD & nSize) { nSize = 0; FILE* fp = fopen(sFileName, "rb"); if(fp == NULL) { printf("Can not open input file '%s'! \n", sFileName); return; } fseek(fp, 0, SEEK_END); nSize = ftell(fp); fseek(fp, 0, SEEK_SET); if(data != NULL) { if(fread(data, 1, nSize, fp) != nSize) { fclose(fp); printf("Read from file '%s' failed! \n", sFileName); return; } printf("Read %d bytes from file '%s'! \n", nSize, sFileName); } fclose(fp); } // 显示HEX码 void showData(BYTE* data, DWORD nSize) { printf("\n****\n"); for(DWORD ii=0; ii < nSize; ii++) { printf("%02x ", data[ii]); if((ii+1) % 16 ==0) printf("\n"); } printf("\n**** %d bytes\n", nSize); } // 准备数据(Auto new outData) void prepareData(BYTE* inData, DWORD inSize, LPCSTR inFileName, BYTE* &outData, DWORD& outSize) { if(inData == NULL && inFileName != NULL) { // Read from file readFile(inFileName, NULL, outSize); if(outSize != 0) { outData = (BYTE*) new char[outSize]; if(outData == NULL) CancelByError(L"Not enough memory. \n"); readFile(inFileName, outData, outSize); } } else { // Read from buffer outSize = inSize; outData = (BYTE*) new char[outSize]; if(outData == NULL) CancelByError(L"Not enough memory. \n"); memcpy(outData, inData, outSize); } } //===================================================================================================== //============================ 离散算法 // SHA1 void hashSHA1(BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL) { // 准备数据 CRYPT_DATA_BLOB orgBlob; memset(&orgBlob, 0, sizeof(orgBlob)); prepareData(inData, inSize, inFileName, orgBlob.pbData, orgBlob.cbData); /**//* BOOL WINAPI CryptAcquireContext( __out HCRYPTPROV* phProv, __in LPCTSTR pszContainer, __in LPCTSTR pszProvider, __in DWORD dwProvType, __in DWORD dwFlags ); */ // 获取CSP句柄 HCRYPTPROV hProv = NULL; if(!CryptAcquireContext( &hProv, // 返回的句柄 NULL, // CSP 容器名称 NULL, // CSP 提供者名称 PROV_RSA_FULL, // CSP 提供者类型 0)) // 附加参数: { delete [] orgBlob.pbData; CancelByError(L"Get CSP provider context failed! \n"); } /**//* BOOL WINAPI CryptCreateHash( __in HCRYPTPROV hProv, __in ALG_ID Algid, __in HCRYPTKEY hKey, __in DWORD dwFlags, __out HCRYPTHASH* phHash ); */ // 创建HASH句柄 HCRYPTHASH hHash = NULL; if(!CryptCreateHash( hProv, // 容器句柄 CALG_SHA1, // 算法标识 NULL, // 算法使用的Key 0, // 算法标识 &hHash)) // 返回的HASH对象 { delete [] orgBlob.pbData; CryptReleaseContext(hProv, 0); CancelByError(L"Get SHA1 provider failed!\n"); } /**//* BOOL WINAPI CryptHashData( __in HCRYPTHASH hHash, __in BYTE* pbData, __in DWORD dwDataLen, __in DWORD dwFlags ); */ // 添加HASH内容 if(!CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0)) { delete [] orgBlob.pbData; CryptReleaseContext(hProv, 0); CancelByError(L"Calc SHA1 data failed!\n"); } /**//* TODO: Calc other blocks if(CryptHashData(hHash, (BYTE*) "12345", 5, 0) == 0) { CancelByError(L"Calc SHA1 data failed!\n"); return; } */ /**//* BOOL WINAPI CryptGetHashParam( __in HCRYPTHASH hHash, __in DWORD dwParam, __out BYTE* pbData, __in_out DWORD* pdwDataLen, __in DWORD dwFlags ); */ // 获取HASH值 BYTE byHashVal[21]; // SHA1 output have 20 bytes. memset(byHashVal, 0x00, 21); DWORD dwDataLen = 20; if(!CryptGetHashParam(hHash, HP_HASHVAL, byHashVal, &dwDataLen, 0)) { delete [] orgBlob.pbData; CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); CancelByError(L"Calc SHA1 data failed!\n"); } showData(byHashVal, dwDataLen); if(outFileName != NULL) { writeFile(outFileName, byHashVal, dwDataLen); } // 清理 delete [] orgBlob.pbData; if(hHash != NULL) { CryptDestroyHash(hHash); hHash = NULL; } if(hProv != NULL) { CryptReleaseContext(hProv, 0); hProv = NULL; } } // ============================ 对称加密解密 // DES(CBC/PKCS5Padding) void DESEncrypt(BYTE* key, BYTE* iv, BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL) { // 准备数据 CRYPT_DATA_BLOB orgBlob; memset(&orgBlob, 0, sizeof(orgBlob)); prepareData(inData, inSize, inFileName, orgBlob.pbData, orgBlob.cbData); /**//* BOOL WINAPI CryptAcquireContext( __out HCRYPTPROV* phProv, __in LPCTSTR pszContainer, __in LPCTSTR pszProvider, __in DWORD dwProvType, __in DWORD dwFlags ); */ // 获取CSP句柄 HCRYPTPROV hProv = NULL; if(!CryptAcquireContext( &hProv, // 返回的句柄 NULL, // CSP 容器名称 NULL, // CSP 提供者名称 PROV_RSA_FULL, // CSP 提供者类型 0)) // 附加参数: { delete [] orgBlob.pbData; CancelByError(L"Get CSP provider context failed!\n"); } // 创建 Key struct keyBlob { BLOBHEADER hdr; DWORD cbKeySize; BYTE rgbKeyData[8]; } keyBlob; keyBlob.hdr.bType = PLAINTEXTKEYBLOB; keyBlob.hdr.bVersion = CUR_BLOB_VERSION; keyBlob.hdr.reserved = 0; keyBlob.hdr.aiKeyAlg = CALG_DES; keyBlob.cbKeySize = 8; CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize); /**//* BOOL WINAPI CryptImportKey( __in HCRYPTPROV hProv, __in BYTE* pbData, __in DWORD dwDataLen, __in HCRYPTKEY hPubKey, __in DWORD dwFlags, __out HCRYPTKEY* phKey ); */ HCRYPTKEY hKey = NULL; if (!CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, CRYPT_EXPORTABLE, &hKey)) { delete [] orgBlob.pbData; CryptReleaseContext(hProv, 0); CancelByError(L"Create key failed!\n"); } /**//* BOOL WINAPI CryptSetKeyParam( __in HCRYPTKEY hKey, __in DWORD dwParam, __in const BYTE* pbData, __in DWORD dwFlags ); */ // 设置初始向量 if(iv == NULL) { if(!CryptSetKeyParam(hKey, KP_IV, key, 0)) { delete [] orgBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"Set key's IV parameter failed!\n"); } } else { if(!CryptSetKeyParam(hKey, KP_IV, iv, 0)) { delete [] orgBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"Set key's IV parameter failed!\n"); } } /**//* BOOL WINAPI CryptEncrypt( __in HCRYPTKEY hKey, __in HCRYPTHASH hHash, __in BOOL Final, __in DWORD dwFlags, __in_out BYTE* pbData, __in_out DWORD* pdwDataLen, __in DWORD dwBufLen ); */ // 加密处理 CRYPT_DATA_BLOB encBlob; memset(&encBlob, 0, sizeof(encBlob)); encBlob.cbData = orgBlob.cbData; encBlob.pbData = (BYTE*) new char[(orgBlob.cbData/8+1)*8]; memcpy(encBlob.pbData, orgBlob.pbData, orgBlob.cbData); if(!CryptEncrypt(hKey, NULL, TRUE, 0, encBlob.pbData, &encBlob.cbData, (orgBlob.cbData/8+1)*8)) { delete [] orgBlob.pbData; delete [] encBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"DES encrypt failed!\n"); } showData(encBlob.pbData, encBlob.cbData); if(outFileName != NULL) { writeFile(outFileName, encBlob.pbData, encBlob.cbData); } // 清理 delete [] orgBlob.pbData; delete [] encBlob.pbData; if(hKey != NULL) { CryptDestroyKey(hKey); hKey = NULL; } if(hProv != NULL) { CryptReleaseContext(hProv, 0); hProv = NULL; } } // AES-128/CBC/PKCS5Padding // AES-256: KeySize=256, IVSize=128, Result=128 void AESEncrypt(BYTE* key, BYTE* iv, BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL) { // 准备数据 CRYPT_DATA_BLOB orgBlob; memset(&orgBlob, 0, sizeof(orgBlob)); prepareData(inData, inSize, inFileName, orgBlob.pbData, orgBlob.cbData); /**//* BOOL WINAPI CryptAcquireContext( __out HCRYPTPROV* phProv, __in LPCTSTR pszContainer, __in LPCTSTR pszProvider, __in DWORD dwProvType, __in DWORD dwFlags ); */ HCRYPTPROV hProv = NULL; if(!CryptAcquireContext( &hProv, // 返回的句柄 NULL, // CSP 容器名称 NULL, // CSP 提供者名称 PROV_RSA_AES, // CSP 提供者类型 0)) // 附加参数: { delete [] orgBlob.pbData; CancelByError(L"Get provider context failed!\n"); } // 创建 Key struct keyBlob { BLOBHEADER hdr; DWORD cbKeySize; BYTE rgbKeyData[16]; // FOR AES-256 = 32 } keyBlob; keyBlob.hdr.bType = PLAINTEXTKEYBLOB; keyBlob.hdr.bVersion = CUR_BLOB_VERSION; keyBlob.hdr.reserved = 0; keyBlob.hdr.aiKeyAlg = CALG_AES_128; // FOR AES-256 = CALG_AES_256 keyBlob.cbKeySize = 16; // FOR AES-256 = 32 CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize); /**//* BOOL WINAPI CryptImportKey( __in HCRYPTPROV hProv, __in BYTE* pbData, __in DWORD dwDataLen, __in HCRYPTKEY hPubKey, __in DWORD dwFlags, __out HCRYPTKEY* phKey ); */ HCRYPTKEY hKey = NULL; if (!CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, CRYPT_EXPORTABLE, &hKey)) { delete [] orgBlob.pbData; CryptReleaseContext(hProv, 0); CancelByError(L"Create key failed!\n"); } /**//* BOOL WINAPI CryptSetKeyParam( __in HCRYPTKEY hKey, __in DWORD dwParam, __in const BYTE* pbData, __in DWORD dwFlags ); */ // 设置初始向量 if(iv == NULL) { if(!CryptSetKeyParam(hKey, KP_IV, key, 0)) { delete [] orgBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"Set key's IV parameter failed!\n"); } } else { if(!CryptSetKeyParam(hKey, KP_IV, iv, 0)) { delete [] orgBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"Set key's IV parameter failed!\n"); } } /**//* BOOL WINAPI CryptEncrypt( __in HCRYPTKEY hKey, __in HCRYPTHASH hHash, __in BOOL Final, __in DWORD dwFlags, __in_out BYTE* pbData, __in_out DWORD* pdwDataLen, __in DWORD dwBufLen ); */ // 加密处理 CRYPT_DATA_BLOB encBlob; memset(&encBlob, 0, sizeof(encBlob)); encBlob.cbData = orgBlob.cbData; encBlob.pbData = (BYTE*) new char[(orgBlob.cbData/16+1)*16]; memcpy(encBlob.pbData, orgBlob.pbData, orgBlob.cbData); if(!CryptEncrypt(hKey, NULL, TRUE, 0, encBlob.pbData, &encBlob.cbData, (orgBlob.cbData/16+1)*16)) { delete [] orgBlob.pbData; delete [] encBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"AES encrypt failed!\n"); } showData(encBlob.pbData, encBlob.cbData); if(outFileName != NULL) { writeFile(outFileName, encBlob.pbData, encBlob.cbData); } // 释放获取的对象 delete [] orgBlob.pbData; delete [] encBlob.pbData; if(hKey != NULL) { CryptDestroyKey(hKey); hKey = NULL; } if(hProv != NULL) { CryptReleaseContext(hProv, 0); hProv = NULL; } } // AES-128/CBC/PKCS5Padding // AES-256: KeySize=256, IVSize=128, Result=128 void AESDecrypt(BYTE* key, BYTE* iv, BYTE* inData, int inSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL) { // 准备数据 CRYPT_DATA_BLOB encBlob; memset(&encBlob, 0, sizeof(encBlob)); prepareData(inData, inSize, inFileName, encBlob.pbData, encBlob.cbData); /**//* BOOL WINAPI CryptAcquireContext( __out HCRYPTPROV* phProv, __in LPCTSTR pszContainer, __in LPCTSTR pszProvider, __in DWORD dwProvType, __in DWORD dwFlags ); */ HCRYPTPROV hProv = NULL; if(!CryptAcquireContext( &hProv, // 返回的句柄 NULL, // CSP key 容器名称 NULL, // CSP 提供者名称 PROV_RSA_AES, // CSP 提供者类型 0)) // 附加参数: { delete [] encBlob.pbData; CancelByError(L"Get provider context failed!\n"); } // 创建 Key struct keyBlob { BLOBHEADER hdr; DWORD cbKeySize; BYTE rgbKeyData[16]; // FOR AES-256 = 32 } keyBlob; keyBlob.hdr.bType = PLAINTEXTKEYBLOB; keyBlob.hdr.bVersion = CUR_BLOB_VERSION; keyBlob.hdr.reserved = 0; keyBlob.hdr.aiKeyAlg = CALG_AES_128; // FOR AES-256 = CALG_AES_256 keyBlob.cbKeySize = 16; // FOR AES-256 = 32 CopyMemory(keyBlob.rgbKeyData, key, keyBlob.cbKeySize); /**//* BOOL WINAPI CryptImportKey( __in HCRYPTPROV hProv, __in BYTE* pbData, __in DWORD dwDataLen, __in HCRYPTKEY hPubKey, __in DWORD dwFlags, __out HCRYPTKEY* phKey ); */ HCRYPTKEY hKey = NULL; if (!CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), NULL, CRYPT_EXPORTABLE, &hKey)) { delete [] encBlob.pbData; CryptReleaseContext(hProv, 0); CancelByError(L"Create key failed!\n"); } /**//* BOOL WINAPI CryptSetKeyParam( __in HCRYPTKEY hKey, __in DWORD dwParam, __in const BYTE* pbData, __in DWORD dwFlags ); */ // 设置初始向量 if(iv == NULL) { if(!CryptSetKeyParam(hKey, KP_IV, key, 0)) { delete [] encBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"Set key's IV parameter failed!\n"); } } else { if(!CryptSetKeyParam(hKey, KP_IV, iv, 0)) { delete [] encBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"Set key's IV parameter failed!\n"); } } /**//* BOOL WINAPI CryptDecrypt( __in HCRYPTKEY hKey, __in HCRYPTHASH hHash, __in BOOL Final, __in DWORD dwFlags, __in_out BYTE* pbData, __in_out DWORD* pdwDataLen ); */ // 加密处理 CRYPT_DATA_BLOB orgBlob; memset(&orgBlob, 0, sizeof(orgBlob)); orgBlob.cbData = encBlob.cbData; orgBlob.pbData = (BYTE*) new char[encBlob.cbData]; memcpy(orgBlob.pbData, encBlob.pbData, encBlob.cbData); if(!CryptDecrypt(hKey, NULL, TRUE, 0, orgBlob.pbData, &orgBlob.cbData)) { delete [] orgBlob.pbData; delete [] encBlob.pbData; CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); CancelByError(L"AES encrypt failed!\n"); } showData(orgBlob.pbData, orgBlob.cbData); if(outFileName != NULL) { writeFile(outFileName, orgBlob.pbData, orgBlob.cbData); } // 清理 delete [] orgBlob.pbData; delete [] encBlob.pbData; if(hKey != NULL) { CryptDestroyKey(hKey); hKey = NULL; } if(hProv != NULL) { CryptReleaseContext(hProv, 0); hProv = NULL; } } // ============================ 证书管理 // 获取证书名称 void viewCertCN(PCCERT_CONTEXT hCert) { /**//* DWORD WINAPI CertGetNameString( __in PCCERT_CONTEXT pCertContext, __in DWORD dwType, __in DWORD dwFlags, __in void* pvTypePara, __out LPTSTR pszNameString, __in DWORD cchNameString ); */ TCHAR sName[1024]; DWORD nNameSize = 1000; DWORD nNameType = 0; // CERT_X500_NAME_STR for FULL name, like C=.., O=.., OU=.., CN=, nNameSize = CertGetNameString( hCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, // CERT_NAME_RDN_TYPE for FULL name. 0, &nNameType, sName, nNameSize); _tprintf(L"CN: %s\n", sName); } // 获取证书签发者 void viewCertIS(PCCERT_CONTEXT hCert) { /**//* DWORD WINAPI CertGetNameString( __in PCCERT_CONTEXT pCertContext, __in DWORD dwType, __in DWORD dwFlags, __in void* pvTypePara, __out LPTSTR pszNameString, __in DWORD cchNameString ); */ TCHAR sName[1024]; DWORD nNameSize = 1000; DWORD nNameType = 0; // CERT_X500_NAME_STR for FULL name, like C=.., O=.., OU=.., CN=, nNameSize = CertGetNameString( hCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, // CERT_NAME_RDN_TYPE for FULL name. CERT_NAME_ISSUER_FLAG, &nNameType, sName, nNameSize); _tprintf(L"IS: %s\n", sName); } // 获取证书序列号 void viewCertSN(PCCERT_CONTEXT hCert) { /**//* BOOL WINAPI CryptFormatObject( __in DWORD dwCertEncodingType, __in DWORD dwFormatType, __in DWORD dwFormatStrType, __in void* pFormatStruct, __in LPCSTR lpszStructType, __in const BYTE* pbEncoded, __in DWORD cbEncoded, __out void* pbFormat, __in_out DWORD* pcbFormat ); */ // 获取解码后的长度 CRYPT_INTEGER_BLOB SerialNumber; BOOL bRet = FALSE; bRet = CryptFormatObject( hCert->dwCertEncodingType, 0, 0, NULL, 0, hCert->pCertInfo->SerialNumber.pbData, hCert->pCertInfo->SerialNumber.cbData, NULL, &SerialNumber.cbData); if(!bRet) { CancelByError(L"Get SerialNumber decode length failed!\n"); } // 分配解码空间 SerialNumber.pbData = (BYTE*) new char[SerialNumber.cbData]; // 获取解码数据 bRet = CryptFormatObject( hCert->dwCertEncodingType, 0, 0, NULL, 0, hCert->pCertInfo->SerialNumber.pbData, hCert->pCertInfo->SerialNumber.cbData, SerialNumber.pbData, &SerialNumber.cbData); if(!bRet) { delete [] SerialNumber.pbData; CancelByError(L"SerialNumber decode failed!\n"); } // char* tmpStr = _com_util::ConvertBSTRToString((BSTR)SerialNumber.pbData); _tprintf(L"SN: %s\n", SerialNumber.pbData); delete [] SerialNumber.pbData; // delete [] tmpStr; } // 获取证书有效期 void viewCertDate(PCCERT_CONTEXT hCert) { CTime dtBefore(hCert->pCertInfo->NotBefore); CTime dtAfter(hCert->pCertInfo->NotAfter); _tprintf(L"DT: %s TO %s\n", dtBefore.Format(L"%Y-%m-%d %H:%M:%S"), dtAfter.Format(L"%Y-%m-%d %H:%M:%S")); } // 校验证书合法性 void verifyCert(PCCERT_CONTEXT hCert) { /**//* LONG WINAPI CertVerifyTimeValidity( __in LPFILETIME pTimeToVerify, __in PCERT_INFO pCertInfo ); */ // 校验证书日期 int nRetCode = CertVerifyTimeValidity(NULL, hCert->pCertInfo); if(nRetCode < 0) { _tprintf(L"Verify cert's date failed: BEFORE date after TODAY!\n"); } if(nRetCode > 0) { _tprintf(L"Verify cert's date failed: Cert has expired!\n"); } if(nRetCode == 0) { _tprintf(L"Verify cert's date succeed!\n"); } // 校验签名者证书 HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT"); if(hCertStore != NULL) { /**//* PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore( __in HCERTSTORE hCertStore, __in PCCERT_CONTEXT pSubjectContext, __in_opt PCCERT_CONTEXT pPrevIssuerContext, __in_out DWORD* pdwFlags ); */ // 2. DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG; PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, NULL, &dwFlags); if(hIssuserCert != NULL) { BOOL bCheckOK = FALSE; while(hIssuserCert != NULL) { /**//* BOOL WINAPI CertVerifySubjectCertificateContext( __in PCCERT_CONTEXT pSubject, __in_opt PCCERT_CONTEXT pIssuer, __in_out DWORD* pdwFlags ); */ // 校验证书签发者信息合法性 dwFlags = CERT_STORE_SIGNATURE_FLAG; if(CertVerifySubjectCertificateContext(hCert, hIssuserCert, &dwFlags)) { if(dwFlags == 0) { _tprintf(L"Verify cert by issuser's cert succeed! \n"); bCheckOK = TRUE; break; } } else { _tprintf(L"Verify cert by issuser's cert failed! \n"); break; } // Next .. hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, hIssuserCert, &dwFlags); } if(!bCheckOK) { _tprintf(L"Verify cert by issuser's cert failed! \n"); } } else { _tprintf(L"Can not find cert issuser's cert!\n"); } if(hIssuserCert != NULL) { CertFreeCertificateContext(hIssuserCert); hIssuserCert = NULL; } } else { _tprintf(L"Open ROOT CertStore failed!\n"); } if(hCertStore != NULL) { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); hCertStore = NULL; } // 校验 CRL 列表
// 1. BYTE* pbCrlData = NULL; DWORD cbCrlData = 0; readFile("c:\\cfcaT.crl", NULL, cbCrlData); if(cbCrlData > 0) { pbCrlData = (BYTE*) new char[cbCrlData]; readFile("c:\\cfcaT.crl", pbCrlData, cbCrlData); } /**//* PCCRL_CONTEXT WINAPI CertCreateCRLContext( __in DWORD dwCertEncodingType, __in const BYTE* pbCrlEncoded, __in DWORD cbCrlEncoded ); */ // 2.转换CRL数据为CRL句柄 PCCRL_CONTEXT hCRL = CertCreateCRLContext(MY_ENCODING_TYPE, pbCrlData, cbCrlData); delete [] pbCrlData; if(hCRL != NULL) { /**//* BOOL WINAPI CertIsValidCRLForCertificate( __in PCCERT_CONTEXT pCert, __in PCCRL_CONTEXT pCRL, __in DWORD dwFlags, __in void* pvReserved */ if(CertIsValidCRLForCertificate(hCert, hCRL, 0, NULL)) { _tprintf(L"CRL is valid for the cert!\n"); } else { _tprintf(L"CRL is invalid for the cert!!\n"); } /**//* BOOL WINAPI CertFindCertificateInCRL( __in PCCERT_CONTEXT pCert, __in PCCRL_CONTEXT pCrlContext, __in DWORD dwFlags, __in_opt void* pvReserved, __out PCRL_ENTRY* pCrlEntry ); */ // Step 4: 检查CRL是否包含该证书 PCRL_ENTRY pCrlEntry = NULL; if(CertFindCertificateInCRL(hCert, hCRL, 0, 0, &pCrlEntry)) { if(pCrlEntry != NULL) { _tprintf(L"Cert has been revoked!\n"); } else { _tprintf(L"Cert not be revoked!\n"); } } else { _tprintf(L"Find cert in CRL failed!\n"); } } else { _tprintf(L"Create CRL context failed!\n"); } if(hCRL != NULL) { CertFreeCRLContext(hCRL); } } // ============================ 证书库管理 // 列出证书库证书 void listCerts(HCERTSTORE hCertStore) { /**//* PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore( __in HCERTSTORE hCertStore, __in PCCERT_CONTEXT pPrevCertContext ); */ _tprintf(L"======== L I S T C E R T I N S T O R E ========\n"); int nCnt = 0; PCCERT_CONTEXT hCert = NULL; while(hCert = CertEnumCertificatesInStore(hCertStore, hCert)) { viewCertCN(hCert); viewCertIS(hCert); viewCertSN(hCert); viewCertDate(hCert); verifyCert(hCert); ++ nCnt; _tprintf(L"-----------------------------\n"); } _tprintf(L"**** Count: %d \n", nCnt); // 清理 if(hCert != NULL) { CertFreeCertificateContext(hCert); hCert = NULL; } } // 列出系统证书库证书 void viewSystemCertStore(LPCTSTR storeName) { /**//* HCERTSTORE WINAPI CertOpenStore( __in LPCSTR lpszStoreProvider, __in DWORD dwMsgAndCertEncodingType, __in HCRYPTPROV_LEGACY hCryptProv, __in DWORD dwFlags, __in const void* pvPara ); */ // 打开证书库 HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, storeName); if(hCertStore == NULL) { CancelByError(L"Open CertStore failed!\n"); } listCerts(hCertStore); // 清理 if(hCertStore != NULL) { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); hCertStore = NULL; } } // 文件证书库(CRT/P7B) void viewCrtCertStore(LPCTSTR crtFileName) { /**//* HCERTSTORE WINAPI CertOpenStore( __in LPCSTR lpszStoreProvider, __in DWORD dwMsgAndCertEncodingType, __in HCRYPTPROV_LEGACY hCryptProv, __in DWORD dwFlags, __in const void* pvPara ); */ // 打开证书库 HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_FILENAME, 0, NULL, 0, crtFileName); if(hCertStore == NULL) { CancelByError(L"Open CertStore failed!\n"); } listCerts(hCertStore); // 清理 if(hCertStore != NULL) { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); hCertStore = NULL; } } // 证书库文件(PFX) void viewPfxCertStore(LPCSTR sCertFileName, LPCTSTR sCertPassword) { // 读取证书库文件 CRYPT_DATA_BLOB pfxData; memset(&pfxData, 0, sizeof(pfxData)); readFile(sCertFileName, NULL, pfxData.cbData); if(pfxData.cbData > 0) { pfxData.pbData = (BYTE*) new char[pfxData.cbData]; readFile(sCertFileName, pfxData.pbData, pfxData.cbData); } /**//* HCERTSTORE WINAPI PFXImportCertStore( __in CRYPT_DATA_BLOB* pPFX, __in LPCWSTR szPassword, __in DWORD dwFlags ); */ HCERTSTORE hCertStore = PFXImportCertStore(&pfxData, sCertPassword, 0); delete [] pfxData.pbData; if(hCertStore == NULL) { CancelByError(L"Open CertStore failed!\n"); } // 列出证书 listCerts(hCertStore); // 清理 if(hCertStore != NULL) { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); hCertStore = NULL; } } // ================================= 数据签名、核签、加密、解密、数字信封
|