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;
}
}
// ================================= 数据签名、核签、加密、解密、数字信封