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;
}
}
// ================================= 数据签名、核签、加密、解密、数字信封
// 裸签
void BareSignData(BYTE * orgData, int orgSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
prepareData(orgData, orgSize, inFileName, orgBlob.pbData, orgBlob.cbData);
// 打开证书库
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(hCert == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Signer certificate not found.");
}
viewCertCN(hCert);
viewCertIS(hCert);
viewCertSN(hCert);
viewCertDate(hCert);
/**//*
BOOL WINAPI CryptAcquireCertificatePrivateKey(
__in PCCERT_CONTEXT pCert,
__in DWORD dwFlags,
__in void* pvReserved,
__out HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey,
__out DWORD* pdwKeySpec,
__out BOOL* pfCallerFreeProvOrNCryptKey
);
*/
// 请求证书私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Acquire certificate privateKey failed!\n");
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hKeyProv, // 容器句柄
CALG_SHA1, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Get SHA1 provider failed!\n");
}
// 计算数据摘要
if(CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0) == 0)
{
delete [] orgBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Calc SHA1 data failed!\n");
}
/**//*
BOOL WINAPI CryptSignHash(
__in HCRYPTHASH hHash,
__in DWORD dwKeySpec,
__in LPCTSTR sDescription,
__in DWORD dwFlags,
__out BYTE* pbSignature,
__in_out DWORD* pdwSigLen
);
*/
DWORD cbSign = 4096;
BYTE pbSign[4096];
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
{
delete [] orgBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Calc SignData failed!\n");
}
reverse(pbSign, cbSign);
showData(pbSign, cbSign);
if(outFileName != NULL)
{
writeFile(outFileName, pbSign, cbSign);
}
// 释放获取的对象
delete [] orgBlob.pbData;
if(hHash != NULL)
{
CryptDestroyHash(hHash);
hHash = NULL;
}
if(hKeyProv != NULL && bFreeKeyProv)
{
CryptReleaseContext(hKeyProv, 0);
hKeyProv = NULL;
}
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
hCertStore = NULL;
}
}
// 校验裸签名
void VerifyBareSignData(BYTE * orgData, int orgSize, BYTE * sigData, int sigSize, LPCSTR orgFileName = NULL, LPCSTR sigFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob, sigBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
memset(&sigBlob, 0, sizeof(sigBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
prepareData(sigData, sigSize, sigFileName, sigBlob.pbData, sigBlob.cbData);
reverse(sigBlob.pbData, sigBlob.cbData);
// 请求容器服务
HCRYPTPROV hProv = NULL;
if(!CryptAcquireContext(
&hProv, // 返回的句柄
NULL, // CSP key 容器名称
NULL, // CSP 提供者名称
PROV_RSA_FULL, // CSP 提供者类型
0)) // 附加参数
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CancelByError(L"Get provider context failed!\n");
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_SHA1, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptReleaseContext(hProv, 0);
CancelByError(L"Get SHA1 provider failed!\n");
}
// 计算数据摘要
if(CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0) == 0)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CancelByError(L"Calc SHA1 data failed!\n");
}
// 获取签名者证书公钥
/**//*
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, L"c:\\ca\\certs\\lny.crt");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CancelByError(L"Open CertStore failed!\n");
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(hCert == NULL)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyHash(hHash);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CryptReleaseContext(hProv, 0);
CancelByError(L"Signer certificate not found.\n");
}
/**//*
BOOL WINAPI CryptImportPublicKeyInfo(
__in HCRYPTPROV hCryptProv,
__in DWORD dwCertEncodingType,
__in PCERT_PUBLIC_KEY_INFO pInfo,
__out HCRYPTKEY* phKey
);
*/
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, MY_ENCODING_TYPE, &hCert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyKey(hPubKey);
CryptDestroyHash(hHash);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CryptReleaseContext(hProv, 0);
CancelByError(L"Get public key from cert failed.");
}
// 校验签名
/**//*
BOOL WINAPI CryptVerifySignature(
__in HCRYPTHASH hHash,
__in BYTE* pbSignature,
__in DWORD dwSigLen,
__in HCRYPTKEY hPubKey,
__in LPCTSTR sDescription,
__in DWORD dwFlags
);
*/
if(!CryptVerifySignature(hHash, sigBlob.pbData, sigBlob.cbData, hPubKey, NULL, 0))
{
_tprintf(L"Verify hash signature failed.\n");
}
else
{
_tprintf(L"Verify hash signature succeed.\n");
}
// 释放获取的对象
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
if(hPubKey != NULL)
{
CryptDestroyKey(hPubKey);
hPubKey = NULL;
}
if(hHash != NULL)
{
CryptDestroyHash(hHash);
hHash = NULL;
}
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
hCertStore = NULL;
}
if(hProv != NULL)
{
CryptReleaseContext(hProv, 0);
hProv = NULL;
}
}
// 含证书的签名(RSA/SHA1RSA)
void SignData(BYTE * orgData, int orgSize, LPCSTR orgFileName = NULL, BOOL bDetached = TRUE, LPCSTR sigFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 打开证书库
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(hCert == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Signer certificate not found.");
}
/**//*
BOOL WINAPI CryptSignMessage(
__in PCRYPT_SIGN_MESSAGE_PARA pSignPara,
__in BOOL fDetachedSignature,
__in DWORD cToBeSigned,
__in const BYTE* rgpbToBeSigned[],
__in DWORD rgcbToBeSigned[],
__out BYTE* pbSignedBlob,
__in_out DWORD* pcbSignedBlob
);
typedef struct _CRYPT_SIGN_MESSAGE_PARA
{
DWORD cbSize;
DWORD dwMsgEncodingType;
PCCERT_CONTEXT pSigningCert;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
void* pvHashAuxInfo;
DWORD cMsgCert;
PCCERT_CONTEXT* rgpMsgCert;
DWORD cMsgCrl;
PCCRL_CONTEXT* rgpMsgCrl;
DWORD cAuthAttr;
PCRYPT_ATTRIBUTE rgAuthAttr;
DWORD cUnauthAttr;
PCRYPT_ATTRIBUTE rgUnauthAttr;
DWORD dwFlags;
DWORD dwInnerContentType;
CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
void pvHashEncryptionAuxInfo;
} CRYPT_SIGN_MESSAGE_PARA;
*/
CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
SigParams.pSigningCert = hCert;
SigParams.HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
SigParams.HashAlgorithm.Parameters.cbData = 0;
SigParams.pvHashAuxInfo = NULL;
SigParams.cMsgCert = 1; // 签名中包含的证书数
SigParams.rgpMsgCert = &hCert;
SigParams.cMsgCrl = 0; // 签名中包含的CRL数
SigParams.rgpMsgCrl = NULL;
SigParams.cAuthAttr = 0;
SigParams.rgAuthAttr = NULL;
SigParams.cUnauthAttr = 0;
SigParams.rgUnauthAttr = NULL;
SigParams.dwInnerContentType = 0;
SigParams.dwFlags = 0;
SigParams.pvHashAuxInfo = NULL;
const BYTE* dataArray[1];
DWORD_PTR sizeArray[1];
dataArray[0] = orgBlob.pbData;
sizeArray[0] = orgBlob.cbData;
// 计算签名值的长度
CRYPT_DATA_BLOB sigData;
memset(&sigData, 0, sizeof(sigData));
if(!CryptSignMessage(&SigParams, bDetached, 1, dataArray, sizeArray, NULL, &(sigData.cbData)))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Get sign data size failed!\n");
}
// 分配内存
sigData.pbData = (BYTE*) new char[sigData.cbData];
if(sigData.pbData == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Not enough memory. \n");
}
// 签名
if(!CryptSignMessage(&SigParams, bDetached, 1, dataArray, sizeArray, sigData.pbData, &(sigData.cbData)))
{
delete [] orgBlob.pbData;
delete [] sigData.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Sign data failed!\n");
}
showData(sigData.pbData, sigData.cbData);
if(sigFileName != NULL)
{
writeFile(sigFileName, sigData.pbData, sigData.cbData);
}
// 释放获取的对象
delete [] orgBlob.pbData;
delete [] sigData.pbData;
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
hCertStore = NULL;
}
}
// 校验无原文的签名
void VerifyDetachedSignData(BYTE * orgData, DWORD orgSize, LPCSTR orgFileName, LPCSTR sigFileName)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob, sigBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
memset(&sigBlob, 0, sizeof(sigBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
prepareData(NULL, 0, sigFileName, sigBlob.pbData, sigBlob.cbData);
// 设定校验参数
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;
/**//*
BOOL WINAPI CryptVerifyDetachedMessageSignature(
__in PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
__in DWORD dwSignerIndex,
__in const BYTE* pbDetachedSignBlob,
__in DWORD cbDetachedSignBlob,
__in DWORD cToBeSigned,
__in const BYTE* rgpbToBeSigned[],
__in DWORD rgcbToBeSigned[],
__out_opt PCCERT_CONTEXT* ppSignerCert
);
*/
const BYTE* dataArray[1];
DWORD_PTR sizeArray[1];
dataArray[0] = orgBlob.pbData;
sizeArray[0] = orgBlob.cbData;
PCCERT_CONTEXT hCert = NULL;
if(CryptVerifyDetachedMessageSignature(
&VerifyParams,
0,
sigBlob.pbData,
sigBlob.cbData,
1,
dataArray,
sizeArray,
&hCert))
{
_tprintf(L"Verification message succeed.\n");
viewCertCN(hCert);
}
else
{
_tprintf(L"Verification message failed.\n");
}
// 清理
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
}
// 校验含原文的签名
void VerifySignedData(LPCSTR sigFileName, LPCSTR orgFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
prepareData(NULL, 0, sigFileName, sigBlob.pbData, sigBlob.cbData);
// 设定校验参数
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;
/**//*
BOOL WINAPI CryptVerifyMessageSignature(
__in PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
__in DWORD dwSignerIndex,
__in const BYTE* pbSignedBlob,
__in DWORD cbSignedBlob,
__out BYTE* pbDecoded,
__in_out DWORD* pcbDecoded,
__out_opt PCCERT_CONTEXT* ppSignerCert
);
*/
// 获取原文字节数
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!CryptVerifyMessageSignature(
&VerifyParams,
0,
sigBlob.pbData,
sigBlob.cbData,
NULL,
&orgBlob.cbData,
NULL))
{
delete [] sigBlob.pbData;
CancelByError(L"Verification message failed. \n");
}
_tprintf(L"%d bytes needed for the decoded message.\n", orgBlob.cbData);
// 分配内存
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
delete [] sigBlob.pbData;
CancelByError(L"Not enough memory. \n");
}
PCCERT_CONTEXT hCert = NULL;
if(CryptVerifyMessageSignature(
&VerifyParams,
0,
sigBlob.pbData,
sigBlob.cbData,
orgBlob.pbData,
&orgBlob.cbData,
&hCert))
{
_tprintf(L"Verification message succeed. \n");
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
viewCertCN(hCert);
}
else
{
_tprintf(L"Verification message failed. \n");
}
// 清理
delete [] sigBlob.pbData;
delete [] orgBlob.pbData;
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
}
// 使用证书公钥加密
void CertEncrypt(BYTE * orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 获取CSP句柄
HCRYPTPROV hCryptProv = NULL;
if(!CryptAcquireContext(
&hCryptProv, // Address for handle to be returned.
NULL, // Use the current user's logon name.
NULL, // Use the default provider.
PROV_RSA_FULL, // Need to both encrypt and sign.
NULL)) // No flags needed.
{
delete [] orgBlob.pbData;
CancelByError(L"Cryptographic context could not be acquired.");
}
// 获取加密者证书
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Open CertStore failed!\n");
}
// 查找签名者证书
PCCERT_CONTEXT pCert = NULL;
pCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pCert == NULL)
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Encrypter certificate not found.");
}
_tprintf(L"Encrypter certificate has been found.\n");
viewCertCN(pCert);
// 设置加密算法
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
memset(&EncryptAlgorithm, 0, sizeof(EncryptAlgorithm));
EncryptAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;
// 设置加密参数
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
memset(&EncryptParams, 0, sizeof(EncryptParams));
EncryptParams.cbSize = sizeof(EncryptParams);
EncryptParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;
// 设置加密的证书清单
PCCERT_CONTEXT RecipientCertArray[1];
RecipientCertArray[0] = pCert;
// 获取加密消息的字节数
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
if(!CryptEncryptMessage(
&EncryptParams,
1,
RecipientCertArray,
orgBlob.pbData,
orgBlob.cbData,
NULL,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Getting encrypted message size failed.");
}
_tprintf(L"The encrypted message is %d bytes. \n",encBlob.cbData);
// 分配空间
encBlob.pbData = (BYTE*) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Memory allocation error while encrypting.");
}
// 加密处理
if(!CryptEncryptMessage(
&EncryptParams,
1,
RecipientCertArray,
orgBlob.pbData,
orgBlob.cbData,
encBlob.pbData,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Encrypted message failed.");
}
showData(encBlob.pbData, encBlob.cbData);
if(encFileName != NULL)
{
writeFile(encFileName, encBlob.pbData, encBlob.cbData);
}
// 清理
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
if(hCryptProv != NULL)
{
CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
}
}
// 使用证书私钥解密
void CertDecrypt(LPCSTR encFileName, LPCSTR orgFileName)
{
// 准备数据
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);
// 获取加密者证书
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 设置解密参数
HCERTSTORE CertStoreArray[] = {hCertStore};
CRYPT_DECRYPT_MESSAGE_PARA DecryptParams;
memset(&DecryptParams, 0, sizeof(DecryptParams));
DecryptParams.cbSize = sizeof(DecryptParams);
DecryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
DecryptParams.cCertStore = 1;
DecryptParams.rghCertStore = CertStoreArray;
// 解密
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!CryptDecryptMessage(
&DecryptParams,
encBlob.pbData,
encBlob.cbData,
NULL,
&orgBlob.cbData,
NULL))
{
delete [] encBlob.pbData;
CancelByError(L"Error getting decrypted message size. \n");
}
_tprintf(L"The size for the decrypted message is: %d.\n", orgBlob.cbData);
// 分配空间
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"Memory allocation error while decrypting. \n");
}
// 解密
if(!CryptDecryptMessage(
&DecryptParams,
encBlob.pbData,
encBlob.cbData,
orgBlob.pbData,
&orgBlob.cbData,
NULL))
{
delete [] encBlob.pbData;
delete [] orgBlob.pbData;
CancelByError(L"Decrypted message failed! \n");
}
_tprintf(L"Message Decrypted Successfully. %d\n", orgBlob.cbData);
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
delete [] encBlob.pbData;
delete [] orgBlob.pbData;
}
// 证书加密并签名生成数字信封
void SignAndEncryptData(BYTE * orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 存取证书库
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"The MY store could not be opened.");
}
// 获取签名者证书
PCCERT_CONTEXT pSignerCertContext = NULL;
pSignerCertContext = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pSignerCertContext == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"Signer cert not found.\n");
}
// 获取接收者证书
PCCERT_CONTEXT pReceiverCertContext = NULL;
pReceiverCertContext = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pReceiverCertContext == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"Receiver cert not found.\n");
}
// pReceiverCertContext = pSignerCertContext;
// 申请签名者私钥服务
DWORD dwKeySpec;
HCRYPTPROV hCryptProv;
if(!CryptAcquireCertificatePrivateKey(
pSignerCertContext,
0,
NULL,
&hCryptProv,
&dwKeySpec,
NULL))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"CryptAcquireCertificatePrivateKey.\n");
}
// 设置签名参数
CRYPT_SIGN_MESSAGE_PARA SignPara;
memset(&SignPara, 0, sizeof(SignPara));
SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType = MY_ENCODING_TYPE;
SignPara.pSigningCert = pSignerCertContext ;
SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignPara.HashAlgorithm.Parameters.cbData = 0;
SignPara.pvHashAuxInfo = NULL;
SignPara.cMsgCert = 1;
SignPara.rgpMsgCert = &pSignerCertContext ;
SignPara.cMsgCrl = 0;
SignPara.rgpMsgCrl = NULL;
SignPara.cAuthAttr = 0;
SignPara.rgAuthAttr = NULL;
SignPara.cUnauthAttr = 0;
SignPara.rgUnauthAttr = NULL;
SignPara.dwFlags = 0;
SignPara.dwInnerContentType = 0;
// 设置加密参数
CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara;
memset(&EncryptPara, 0, sizeof(EncryptPara));
EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE;
EncryptPara.hCryptProv = 0;
EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;
EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
EncryptPara.pvEncryptionAuxInfo = NULL;
EncryptPara.dwFlags = 0;
EncryptPara.dwInnerContentType = 0;
// 设置加密的证书
DWORD cRecipientCert;
PCCERT_CONTEXT rgpRecipientCert[5];
cRecipientCert = 1;
rgpRecipientCert[0] = pReceiverCertContext;
// 获取签名并加密消息长度
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
if(!CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
orgBlob.pbData,
orgBlob.cbData,
NULL,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"Getting Signed&Encrypted message length failed.");
}
_tprintf(L"SignAndEncrypte message size is %d bytes.\n", encBlob.cbData);
// 分配空间
encBlob.pbData = (BYTE*) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"Memory allocation error while SignAndEncrypting. \n");
}
// 签名并加密消息
if(!CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
orgBlob.pbData,
orgBlob.cbData,
encBlob.pbData,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"The message failed to sign and encrypt.");
}
_tprintf(L"The message is signed and encrypted.\n");
showData(encBlob.pbData, encBlob.cbData);
if(encFileName != NULL)
{
writeFile(encFileName, encBlob.pbData, encBlob.cbData);
}
// 清理
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
}
// 解密并校验数字信封
void DecryptAndVerifyData(LPCSTR encFileName, LPCSTR orgFileName)
{
// 准备数据
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);
// 存取证书库
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my");
if(hCertStore == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"The MY store could not be opened.");
}
// 设置解密参数
CRYPT_DECRYPT_MESSAGE_PARA DecryptPara;
memset(&DecryptPara, 0, sizeof(DecryptPara));
DecryptPara.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
DecryptPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
DecryptPara.cCertStore = 1;
DecryptPara.rghCertStore = &hCertStore;
// 设置校验参数
CRYPT_VERIFY_MESSAGE_PARA VerifyPara;
memset(&VerifyPara, 0, sizeof(VerifyPara));
VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyPara.hCryptProv = 0;
VerifyPara.pfnGetSignerCertificate = NULL;
VerifyPara.pvGetArg = NULL;
// 获取解密消息长度
DWORD dwSignerIndex = 0;
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
encBlob.pbData,
encBlob.cbData,
NULL,
&orgBlob.cbData,
NULL,
NULL)))
{
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"Get decrypted message size failed.");
}
_tprintf(L"DecryptAndVerify message size is %d bytes.\n", orgBlob.cbData);
// 分配空间
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"Memory allocation error while DecryptAndVerifyMessage. \n");
}
// 解密并校验
PCCERT_CONTEXT pRecverCert;
PCCERT_CONTEXT pSignerCert;
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
encBlob.pbData,
encBlob.cbData,
orgBlob.pbData,
&orgBlob.cbData,
&pRecverCert,
&pSignerCert)))
{
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"The message failed to sign and encrypt.");
}
_tprintf(L"The message is decrypted and verifyed.\n");
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
viewCertCN(pSignerCert);
viewCertCN(pRecverCert);
// 清理
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
}
// 加密并签名的数字信封(低级)
void EnvelopeData(BYTE * orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 从MY证书库获取签名者证书
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 查找签名者证书
PCCERT_CONTEXT pSignerCert = NULL;
pSignerCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pSignerCert == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Signer certificate not found.");
}
_tprintf(L"Signer certificate has been found.\n");
viewCertCN(pSignerCert);
// 申请私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(pSignerCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Acquire certificate privateKey failed!\n");
}
// 设置签名算法
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
memset(&HashAlgorithm, 0, sizeof(HashAlgorithm));
HashAlgorithm.pszObjId = szOID_RSA_MD5;
// 设置签名编码参数
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hKeyProv;
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;
SignerEncodeInfoArray[0] = SignerEncodeInfo;
// 设置签名证书
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
SignerCertBlob.pbData = pSignerCert->pbCertEncoded;
SignerCertBlobArray[0] = SignerCertBlob;
// 设置签名编码参数
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
SignedMsgEncodeInfo.cCrlEncoded = 0;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;
// 获取编码输出的签名块长度
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
sigBlob.cbData = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE,
0,
CMSG_SIGNED,
&SignedMsgEncodeInfo,
NULL,
orgBlob.cbData);
if(sigBlob.cbData == 0)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Getting signed message length failed.");
}
// 分配编码空间
sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
if(sigBlob.pbData == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Memory allocation failed. \n");
}
// 编码签名消息
HCRYPTMSG hMsg;
hMsg = CryptMsgOpenToEncode(
MY_ENCODING_TYPE, // encoding type
0, // flags
CMSG_SIGNED, // message type
&SignedMsgEncodeInfo, // pointer to structure
NULL, // inner content OID
NULL); // stream information (not used)
if(hMsg == NULL)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"The message to be encoded failed. \n");
}
// 添加数据
if(!CryptMsgUpdate(
hMsg, // handle to the message
orgBlob.pbData, // pointer to the content
orgBlob.cbData, // size of the content
TRUE)) // last call
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"CryptMsgUpdate failed.\n");
}
// 获取签名结果
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CONTENT_PARAM, // parameter type
0, // index
sigBlob.pbData, // pointer to the BLOB
&sigBlob.cbData)) // size of the BLOB
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"CryptMsgGetParam signed message failed.\n");
}
// 清理签名部分
delete [] orgBlob.pbData;
if(pSignerCert != NULL)
{
CertFreeCertificateContext(pSignerCert);
pSignerCert = NULL;
}
if(hMsg != NULL)
{
CryptMsgClose(hMsg);
hMsg = NULL;
}
if(hKeyProv != NULL)
{
CryptReleaseContext(hKeyProv, 0);
hKeyProv = NULL;
}
// ----------------------- 签名结束:得到带原文的签名
// 公钥加密
// 查找接收者证书
PCCERT_CONTEXT pRecverCert = NULL;
pRecverCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pRecverCert == NULL)
{
delete [] sigBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Receiver certificate not found.");
}
_tprintf(L"Receiver certificate has been found.\n");
viewCertCN(pRecverCert);
// 设置加密证书
PCERT_INFO RecipCertArray[1];
RecipCertArray[0] = pRecverCert->pCertInfo;
// 设置加密算法
CRYPT_ALGORITHM_IDENTIFIER ContentEncryptAlgorithm;
memset(&ContentEncryptAlgorithm, 0, sizeof(ContentEncryptAlgorithm));
ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC2CBC;
// 设置信封参数
CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;
memset(&EnvelopedEncodeInfo, 0, sizeof(CMSG_ENVELOPED_ENCODE_INFO));
EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
EnvelopedEncodeInfo.hCryptProv = NULL;
EnvelopedEncodeInfo.ContentEncryptionAlgorithm = ContentEncryptAlgorithm;
EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;
EnvelopedEncodeInfo.cRecipients = 1;
EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;
// 获取消息编码的长度
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
encBlob.cbData = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE,
0,
CMSG_ENVELOPED,
&EnvelopedEncodeInfo,
NULL,
sigBlob.cbData);
if(encBlob.cbData == 0)
{
delete [] sigBlob.pbData;
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Getting enveloped cbEncodedBlob length failed.");
}
_tprintf(L"Enveloped message size is %d bytes.", encBlob.cbData);
// 分配编码空间
encBlob.pbData = (BYTE *) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
delete [] sigBlob.pbData;
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Memory allocation failed. \n");
}
// 编码加密
hMsg = CryptMsgOpenToEncode(
MY_ENCODING_TYPE, // encoding type
0, // flags
CMSG_ENVELOPED, // message type
&EnvelopedEncodeInfo, // pointer to structure
NULL, // szOID_RSA_signedData, // inner content OID
NULL);
if(hMsg == NULL)
{
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"The message open to be encode failed. \n");
}
// 添加数据
if(!CryptMsgUpdate(
hMsg, // handle to the message
sigBlob.pbData, // pointer to the content
sigBlob.cbData, // size of the content
TRUE)) // last call
{
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Enveloped CryptMsgUpdate failed.\n");
}
// 获取加密结果
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CONTENT_PARAM, // parameter type
0, // index
encBlob.pbData, // pointer to the BLOB
&encBlob.cbData)) // size of the BLOB
{
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"CryptMsgGetParam enveloped message failed.\n");
}
showData(encBlob.pbData, encBlob.cbData);
if(encFileName != NULL)
{
writeFile(encFileName, encBlob.pbData, encBlob.cbData);
}
// 清理
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
if(hMsg != NULL)
{
CryptMsgClose(hMsg);
hMsg = NULL;
}
if(pRecverCert != NULL)
{
CertFreeCertificateContext(pRecverCert);
pRecverCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
}
// 解密信封并校验签名(低级)
void DevelopeData(LPCSTR encFileName, LPCSTR orgFileName)
{
// 准备数据
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);
// Open
HCRYPTMSG hMsg = NULL;
hMsg = CryptMsgOpenToDecode(
MY_ENCODING_TYPE, // Encoding type.
0, // Flags.
0, // Use the default message type which is listed in the message header.
NULL, // Cryptographic provider. Use NULL for the default provider.
NULL, // Recipient information.
NULL); // Stream information.
if(hMsg == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"Failed in CryptMsgOpenToDecode.");
}
// Update
if(!CryptMsgUpdate(
hMsg, // Handle to the message
encBlob.pbData, // Pointer to the encoded BLOB
encBlob.cbData, // Size of the encoded BLOB
TRUE))
{
delete [] encBlob.pbData;
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgUpdate.");
}
// 释放加密数据
delete [] encBlob.pbData;
// 开始操作解码后的加密数据 ================================
// 消息类型
DWORD dwType = 0;
DWORD dwSize = sizeof(dwType);
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_TYPE_PARAM, // Parameter type
0, // Index
&dwType, // Buffer
&dwSize)) // Size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_TYPE_PARAM.");
}
// 校验消息类型
if (dwType != CMSG_ENVELOPED)
{
CryptMsgClose(hMsg);
CancelByError(L"Not an enveloped data.");
}
// 消息格式
char szTypeName[1024];
dwSize = 1024;
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_INNER_CONTENT_TYPE_PARAM, // Parameter type
0, // Index
szTypeName, // Buffer
&dwSize)) // Size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_INNER_CONTENT_TYPE_PARAM.");
}
// 检查消息格式
if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0)
{
// CryptMsgClose(hMsg);
// CancelByError(L"The inner content is not szOID_PKCS_7_DATA.");
}
// 获取接收者证书大小
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_RECIPIENT_INFO_PARAM, // Parameter type
0, // Index
NULL, // Buffer
&dwSize)) // Size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_RECIPIENT_INFO_PARAM.");
}
// 分配内存
PCERT_INFO pRecverCertInfo = (PCERT_INFO) new char[dwSize];
if (pRecverCertInfo == NULL)
{
CryptMsgClose(hMsg);
CancelByError(L"Not enough memory.");
}
// 获取接收者证书信息
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_RECIPIENT_INFO_PARAM, // Parameter type
0, // Index
pRecverCertInfo, // Buffer
&dwSize)) // Size of the returned
{
delete [] pRecverCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_RECIPIENT_INFO_PARAM.");
}
// 访问证书库
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] pRecverCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Open CertStore failed!\n");
}
// 获取接收者证书
PCCERT_CONTEXT hRcverCertContext = CertGetSubjectCertificateFromStore(hCertStore, MY_ENCODING_TYPE, pRecverCertInfo);
delete [] pRecverCertInfo;
if(hRcverCertContext == NULL)
{
CryptMsgClose(hMsg);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"No matched certificate found in store.");
}
viewCertCN(hRcverCertContext);
// 申请私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(hRcverCertContext, 0, 0, &hCryptProv, &dwKeyType, &bFreeKeyProv))
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Acquire certificate privateKey failed!\n");
}
/**//* ------ 另外一种申请私钥服务的做法:沒验证
bReturn = CertGetCertificateContextProperty(
context,
CERT_KEY_PROV_INFO_PROP_ID ,
NULL,
&dwSize
);
if (!bReturn)
{
CancelByError(L"Failed in CertGetCertificateContextProperty.");
}
CRYPT_KEY_PROV_INFO * key_info = (CRYPT_KEY_PROV_INFO *) malloc (dwSize);
if (!key_info)
CancelByError(L"Not enough memory.");
bReturn = CertGetCertificateContextProperty(
context,
CERT_KEY_PROV_INFO_PROP_ID ,
key_info,
&dwSize
);
if (!bReturn)
{
CancelByError(L"Failed in CertGetCertificateContextProperty.");
}
// acquire a CSP
HCRYPTPROV hCryptProv;
bReturn = CryptAcquireContext(
&hCryptProv, // 返回的句柄
NULL, // CSP key 容器名称
NULL, // CSP 提供者名称
PROV_RSA_FULL, // CSP 提供者类型
0); // 附加参数:
bReturn = CryptAcquireContext(
&hCryptProv,
key_info->pwszContainerName,
key_info->pwszProvName,
key_info->dwProvType,
key_info->dwFlags
);
if (!bReturn)
{
CancelByError(L"Failed in CryptAcquireContext.");
}
*/
// 解密解码的数据
CMSG_CTRL_DECRYPT_PARA para;
para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA);
para.dwKeySpec = dwKeyType;
para.hCryptProv = hCryptProv;
para.dwRecipientIndex = 0;
if(!CryptMsgControl(
hMsg, // Handle to the message
0, // Flags
CMSG_CTRL_DECRYPT, // Control type
¶)) // Pointer to the CERT_INFO
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Failed in CryptMsgControl.");
}
// 获取解密消息大小
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
NULL, //
&sigBlob.cbData)) // Size of the returned
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");
}
// 分配内存
sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
if(sigBlob.pbData == NULL)
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Not enough memory.");
}
// 获取解码消息
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
sigBlob.pbData, //
&sigBlob.cbData)) // Size of the returned
{
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");
}
// 清理解密过程数据
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
_tprintf(L"Enveloped message decrypt successfully. \n");
// ----------------------------------- 解密处理完成:得到一个带原文的签名
// 解码带原文的数字签名
hMsg = CryptMsgOpenToDecode(
MY_ENCODING_TYPE, // Encoding type.
0, // Flags.
0, // Use the default message type which is listed in the message header.
NULL, // Cryptographic provider. Use NULL for the default provider.
NULL, // Recipient information.
NULL); // Stream information.
if(hMsg == NULL)
{
delete [] sigBlob.pbData;
CancelByError(L"Failed in CryptMsgOpenToDecode.");
}
// Update
if(!CryptMsgUpdate(
hMsg, // Handle to the message
sigBlob.pbData, // Pointer to the encoded BLOB
sigBlob.cbData, // Size of the encoded BLOB
TRUE))
{
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgUpdate.");
}
// 释放数字签名数据
delete [] sigBlob.pbData;
// 开始操作解码后的签名数据 ================================
// 获取原文字节数
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
NULL,
&orgBlob.cbData))
{
CryptMsgClose(hMsg);
CancelByError(L"Get the decoded message failed. \n");
}
_tprintf(L"%d bytes needed for the decoded message.\n", orgBlob.cbData);
// 分配内存
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
CryptMsgClose(hMsg);
CancelByError(L"Not enough memory. \n");
}
// 获取原文
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
orgBlob.pbData,
&orgBlob.cbData))
{
delete [] orgBlob.pbData;
CryptMsgClose(hMsg);
CancelByError(L"Get the decoded message failed. \n");
}
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
// 释放原文数据
delete [] orgBlob.pbData;
// 获取签名者证书信息大小
DWORD cbSignerCertInfo;
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CERT_PARAM, // parameter type
0, // index
NULL,
&cbSignerCertInfo)) // size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Get SIGNER_CERT_INFO #1 failed.");
}
// 分配内存
BYTE* pSignerCertInfo = (BYTE*) new char[cbSignerCertInfo];
if(pSignerCertInfo == NULL)
{
CryptMsgClose(hMsg);
CancelByError(L"Not enough memory.");
}
// 获取签名者证书信息
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CERT_PARAM, // parameter type
0, // index
pSignerCertInfo,
&cbSignerCertInfo)) // size of the returned
{
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Get SIGNER_CERT_INFO #1 failed.");
}
// 创建证书上下文
PCCERT_CONTEXT pSignerCertContext = NULL;
pSignerCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE*) pSignerCertInfo, cbSignerCertInfo);
if(pSignerCertContext == NULL)
{
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Get Subject Cert failed. ");
}
viewCertCN(pSignerCertContext);
// 校验数字签名
if(!CryptMsgControl(
hMsg,
0,
CMSG_CTRL_VERIFY_SIGNATURE,
pSignerCertContext->pCertInfo))
{
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCertContext);
CancelByError(L"Verify signature failed. \n");
}
_tprintf(L"Verify signature succeeded. \n");
// 清理
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCertContext);
}
int _tmain( int argc, _TCHAR * argv[])
{
// HASH
// hashSHA1((BYTE*)"123456789012345", 15, NULL, "c:\\li.sha1");
// hashSHA1(NULL, 0, "c:\\li.txt", "c:\\li.sha1");
// Encrypt & Decrypt
// DESEncrypt((BYTE*)"12345678", (BYTE*)"XXXXXXXX", (BYTE*)"123456789012345", 15, NULL, "c:\\li.des");
// DESEncrypt((BYTE*)"12345678", (BYTE*)"XXXXXXXX", NULL, 0, "c:\\li.txt", "c:\\li.des");
// AESEncrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", (BYTE*)"123456789012345", 15, NULL, "c:\\li.aes");
// AESEncrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", NULL, 0, "c:\\1.txt", "c:\\li.aes");
// BYTE* pEncData = (BYTE*) "\xCA\x89\x39\xC2\x2F\xB3\x4B\x39\x54\x2e\xd6\xb1\x14\xc9\x31\x10";
// AESDecrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", pEncData, 16, NULL, "c:\\li.org");
// AESDecrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", NULL, 0, "c:\\li.aes", "c:\\1.org");
// CertStore & Cert
// viewSystemCertStore(L"MY");
// viewSystemCertStore(L"CA");
// viewSystemCertStore(L"ROOT");
// viewCrtCertStore(L"c:\\ca\\certs\\lny.crt");
// viewCrtCertStore(L"c:\\cfcaT.p7b");
// viewPfxCertStore("c:\\ca\\lny.pfx", L"welcome2008");
// HASH SignData
// BareSignData((BYTE*) "1234567890", 10, NULL, "c:\\li.sha1.sig");
// VerifyBareSignData((BYTE*) "1234567890", 10, NULL, 0, NULL, "c:\\li.sha1.sig");
// BareSignData(NULL, 0, "c:\\li.txt", "c:\\li.sha1.sig");
// VerifyBareSignData(NULL, 0, NULL, 0, "c:\\li.txt", "c:\\li.sha1.sig");
// TACHED SignData
// SignData((BYTE*)"1234567890", 10, NULL, FALSE, "c:\\li.tch.sig");
// VerifySignedData("c:\\li.tch.sig");
// SignData(NULL, 0, "c:\\li.txt", FALSE, "c:\\li.tch.sig");
// VerifySignedData("c:\\1li.tch.sig", "c:\\li.txt.org");
// DETACHED SignData
// SignData((BYTE*)"1234567890", 10, NULL, TRUE, "c:\\li.detch.sig");
// VerifyDetachedSignData((BYTE*) "1234567890", 10, NULL, "c:\\li.detch.sig");
// VerifyDetachedSignData(NULL, 0, "c:\\li.txt", "c:\\li.detch.sig");
// Cert Encrypt & Decrypt
// CertEncrypt((BYTE*)"1234567890", 10, NULL, "c:\\li.enc");
// CertEncrypt(NULL, 0, "c:\\li.txt", "c:\\li.enc");
// CertDecrypt("c:\\li.enc", "c:\\li.org");
// SignAndEncryptData((BYTE*)"1234567890", 10, NULL, "c:\\li.enc");
// DecryptAndVerifyData("c:\\li.enc", "c:\\li.org");
printf("========================================================================\n");
// Other cert Encrypt & Decrypt (低级消息函数)
// EnvelopeData((BYTE*)"welcome2008WWWWW", 17, NULL, "c:\\li.enc");
DevelopeData("c:\\li.enc", "c:\\li.org");
pause();
return 0;
}
//
#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;
}
}
// ================================= 数据签名、核签、加密、解密、数字信封
// 裸签
void BareSignData(BYTE * orgData, int orgSize, LPCSTR inFileName = NULL, LPCSTR outFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
prepareData(orgData, orgSize, inFileName, orgBlob.pbData, orgBlob.cbData);
// 打开证书库
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(hCert == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Signer certificate not found.");
}
viewCertCN(hCert);
viewCertIS(hCert);
viewCertSN(hCert);
viewCertDate(hCert);
/**//*
BOOL WINAPI CryptAcquireCertificatePrivateKey(
__in PCCERT_CONTEXT pCert,
__in DWORD dwFlags,
__in void* pvReserved,
__out HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey,
__out DWORD* pdwKeySpec,
__out BOOL* pfCallerFreeProvOrNCryptKey
);
*/
// 请求证书私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Acquire certificate privateKey failed!\n");
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hKeyProv, // 容器句柄
CALG_SHA1, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Get SHA1 provider failed!\n");
}
// 计算数据摘要
if(CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0) == 0)
{
delete [] orgBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Calc SHA1 data failed!\n");
}
/**//*
BOOL WINAPI CryptSignHash(
__in HCRYPTHASH hHash,
__in DWORD dwKeySpec,
__in LPCTSTR sDescription,
__in DWORD dwFlags,
__out BYTE* pbSignature,
__in_out DWORD* pdwSigLen
);
*/
DWORD cbSign = 4096;
BYTE pbSign[4096];
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
{
delete [] orgBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Calc SignData failed!\n");
}
reverse(pbSign, cbSign);
showData(pbSign, cbSign);
if(outFileName != NULL)
{
writeFile(outFileName, pbSign, cbSign);
}
// 释放获取的对象
delete [] orgBlob.pbData;
if(hHash != NULL)
{
CryptDestroyHash(hHash);
hHash = NULL;
}
if(hKeyProv != NULL && bFreeKeyProv)
{
CryptReleaseContext(hKeyProv, 0);
hKeyProv = NULL;
}
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
hCertStore = NULL;
}
}
// 校验裸签名
void VerifyBareSignData(BYTE * orgData, int orgSize, BYTE * sigData, int sigSize, LPCSTR orgFileName = NULL, LPCSTR sigFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob, sigBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
memset(&sigBlob, 0, sizeof(sigBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
prepareData(sigData, sigSize, sigFileName, sigBlob.pbData, sigBlob.cbData);
reverse(sigBlob.pbData, sigBlob.cbData);
// 请求容器服务
HCRYPTPROV hProv = NULL;
if(!CryptAcquireContext(
&hProv, // 返回的句柄
NULL, // CSP key 容器名称
NULL, // CSP 提供者名称
PROV_RSA_FULL, // CSP 提供者类型
0)) // 附加参数
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CancelByError(L"Get provider context failed!\n");
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_SHA1, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptReleaseContext(hProv, 0);
CancelByError(L"Get SHA1 provider failed!\n");
}
// 计算数据摘要
if(CryptHashData(hHash, orgBlob.pbData, orgBlob.cbData, 0) == 0)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CancelByError(L"Calc SHA1 data failed!\n");
}
// 获取签名者证书公钥
/**//*
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, L"c:\\ca\\certs\\lny.crt");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CancelByError(L"Open CertStore failed!\n");
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(hCert == NULL)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyHash(hHash);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CryptReleaseContext(hProv, 0);
CancelByError(L"Signer certificate not found.\n");
}
/**//*
BOOL WINAPI CryptImportPublicKeyInfo(
__in HCRYPTPROV hCryptProv,
__in DWORD dwCertEncodingType,
__in PCERT_PUBLIC_KEY_INFO pInfo,
__out HCRYPTKEY* phKey
);
*/
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, MY_ENCODING_TYPE, &hCert->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptDestroyKey(hPubKey);
CryptDestroyHash(hHash);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CryptReleaseContext(hProv, 0);
CancelByError(L"Get public key from cert failed.");
}
// 校验签名
/**//*
BOOL WINAPI CryptVerifySignature(
__in HCRYPTHASH hHash,
__in BYTE* pbSignature,
__in DWORD dwSigLen,
__in HCRYPTKEY hPubKey,
__in LPCTSTR sDescription,
__in DWORD dwFlags
);
*/
if(!CryptVerifySignature(hHash, sigBlob.pbData, sigBlob.cbData, hPubKey, NULL, 0))
{
_tprintf(L"Verify hash signature failed.\n");
}
else
{
_tprintf(L"Verify hash signature succeed.\n");
}
// 释放获取的对象
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
if(hPubKey != NULL)
{
CryptDestroyKey(hPubKey);
hPubKey = NULL;
}
if(hHash != NULL)
{
CryptDestroyHash(hHash);
hHash = NULL;
}
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
hCertStore = NULL;
}
if(hProv != NULL)
{
CryptReleaseContext(hProv, 0);
hProv = NULL;
}
}
// 含证书的签名(RSA/SHA1RSA)
void SignData(BYTE * orgData, int orgSize, LPCSTR orgFileName = NULL, BOOL bDetached = TRUE, LPCSTR sigFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 打开证书库
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(hCert == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Signer certificate not found.");
}
/**//*
BOOL WINAPI CryptSignMessage(
__in PCRYPT_SIGN_MESSAGE_PARA pSignPara,
__in BOOL fDetachedSignature,
__in DWORD cToBeSigned,
__in const BYTE* rgpbToBeSigned[],
__in DWORD rgcbToBeSigned[],
__out BYTE* pbSignedBlob,
__in_out DWORD* pcbSignedBlob
);
typedef struct _CRYPT_SIGN_MESSAGE_PARA
{
DWORD cbSize;
DWORD dwMsgEncodingType;
PCCERT_CONTEXT pSigningCert;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
void* pvHashAuxInfo;
DWORD cMsgCert;
PCCERT_CONTEXT* rgpMsgCert;
DWORD cMsgCrl;
PCCRL_CONTEXT* rgpMsgCrl;
DWORD cAuthAttr;
PCRYPT_ATTRIBUTE rgAuthAttr;
DWORD cUnauthAttr;
PCRYPT_ATTRIBUTE rgUnauthAttr;
DWORD dwFlags;
DWORD dwInnerContentType;
CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
void pvHashEncryptionAuxInfo;
} CRYPT_SIGN_MESSAGE_PARA;
*/
CRYPT_SIGN_MESSAGE_PARA SigParams;
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
SigParams.pSigningCert = hCert;
SigParams.HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
SigParams.HashAlgorithm.Parameters.cbData = 0;
SigParams.pvHashAuxInfo = NULL;
SigParams.cMsgCert = 1; // 签名中包含的证书数
SigParams.rgpMsgCert = &hCert;
SigParams.cMsgCrl = 0; // 签名中包含的CRL数
SigParams.rgpMsgCrl = NULL;
SigParams.cAuthAttr = 0;
SigParams.rgAuthAttr = NULL;
SigParams.cUnauthAttr = 0;
SigParams.rgUnauthAttr = NULL;
SigParams.dwInnerContentType = 0;
SigParams.dwFlags = 0;
SigParams.pvHashAuxInfo = NULL;
const BYTE* dataArray[1];
DWORD_PTR sizeArray[1];
dataArray[0] = orgBlob.pbData;
sizeArray[0] = orgBlob.cbData;
// 计算签名值的长度
CRYPT_DATA_BLOB sigData;
memset(&sigData, 0, sizeof(sigData));
if(!CryptSignMessage(&SigParams, bDetached, 1, dataArray, sizeArray, NULL, &(sigData.cbData)))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Get sign data size failed!\n");
}
// 分配内存
sigData.pbData = (BYTE*) new char[sigData.cbData];
if(sigData.pbData == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Not enough memory. \n");
}
// 签名
if(!CryptSignMessage(&SigParams, bDetached, 1, dataArray, sizeArray, sigData.pbData, &(sigData.cbData)))
{
delete [] orgBlob.pbData;
delete [] sigData.pbData;
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Sign data failed!\n");
}
showData(sigData.pbData, sigData.cbData);
if(sigFileName != NULL)
{
writeFile(sigFileName, sigData.pbData, sigData.cbData);
}
// 释放获取的对象
delete [] orgBlob.pbData;
delete [] sigData.pbData;
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
hCertStore = NULL;
}
}
// 校验无原文的签名
void VerifyDetachedSignData(BYTE * orgData, DWORD orgSize, LPCSTR orgFileName, LPCSTR sigFileName)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob, sigBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
memset(&sigBlob, 0, sizeof(sigBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
prepareData(NULL, 0, sigFileName, sigBlob.pbData, sigBlob.cbData);
// 设定校验参数
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;
/**//*
BOOL WINAPI CryptVerifyDetachedMessageSignature(
__in PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
__in DWORD dwSignerIndex,
__in const BYTE* pbDetachedSignBlob,
__in DWORD cbDetachedSignBlob,
__in DWORD cToBeSigned,
__in const BYTE* rgpbToBeSigned[],
__in DWORD rgcbToBeSigned[],
__out_opt PCCERT_CONTEXT* ppSignerCert
);
*/
const BYTE* dataArray[1];
DWORD_PTR sizeArray[1];
dataArray[0] = orgBlob.pbData;
sizeArray[0] = orgBlob.cbData;
PCCERT_CONTEXT hCert = NULL;
if(CryptVerifyDetachedMessageSignature(
&VerifyParams,
0,
sigBlob.pbData,
sigBlob.cbData,
1,
dataArray,
sizeArray,
&hCert))
{
_tprintf(L"Verification message succeed.\n");
viewCertCN(hCert);
}
else
{
_tprintf(L"Verification message failed.\n");
}
// 清理
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
}
// 校验含原文的签名
void VerifySignedData(LPCSTR sigFileName, LPCSTR orgFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
prepareData(NULL, 0, sigFileName, sigBlob.pbData, sigBlob.cbData);
// 设定校验参数
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;
/**//*
BOOL WINAPI CryptVerifyMessageSignature(
__in PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
__in DWORD dwSignerIndex,
__in const BYTE* pbSignedBlob,
__in DWORD cbSignedBlob,
__out BYTE* pbDecoded,
__in_out DWORD* pcbDecoded,
__out_opt PCCERT_CONTEXT* ppSignerCert
);
*/
// 获取原文字节数
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!CryptVerifyMessageSignature(
&VerifyParams,
0,
sigBlob.pbData,
sigBlob.cbData,
NULL,
&orgBlob.cbData,
NULL))
{
delete [] sigBlob.pbData;
CancelByError(L"Verification message failed. \n");
}
_tprintf(L"%d bytes needed for the decoded message.\n", orgBlob.cbData);
// 分配内存
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
delete [] sigBlob.pbData;
CancelByError(L"Not enough memory. \n");
}
PCCERT_CONTEXT hCert = NULL;
if(CryptVerifyMessageSignature(
&VerifyParams,
0,
sigBlob.pbData,
sigBlob.cbData,
orgBlob.pbData,
&orgBlob.cbData,
&hCert))
{
_tprintf(L"Verification message succeed. \n");
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
viewCertCN(hCert);
}
else
{
_tprintf(L"Verification message failed. \n");
}
// 清理
delete [] sigBlob.pbData;
delete [] orgBlob.pbData;
if(hCert != NULL)
{
CertFreeCertificateContext(hCert);
hCert = NULL;
}
}
// 使用证书公钥加密
void CertEncrypt(BYTE * orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 获取CSP句柄
HCRYPTPROV hCryptProv = NULL;
if(!CryptAcquireContext(
&hCryptProv, // Address for handle to be returned.
NULL, // Use the current user's logon name.
NULL, // Use the default provider.
PROV_RSA_FULL, // Need to both encrypt and sign.
NULL)) // No flags needed.
{
delete [] orgBlob.pbData;
CancelByError(L"Cryptographic context could not be acquired.");
}
// 获取加密者证书
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Open CertStore failed!\n");
}
// 查找签名者证书
PCCERT_CONTEXT pCert = NULL;
pCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pCert == NULL)
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Encrypter certificate not found.");
}
_tprintf(L"Encrypter certificate has been found.\n");
viewCertCN(pCert);
// 设置加密算法
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
memset(&EncryptAlgorithm, 0, sizeof(EncryptAlgorithm));
EncryptAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;
// 设置加密参数
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
memset(&EncryptParams, 0, sizeof(EncryptParams));
EncryptParams.cbSize = sizeof(EncryptParams);
EncryptParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING;
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;
// 设置加密的证书清单
PCCERT_CONTEXT RecipientCertArray[1];
RecipientCertArray[0] = pCert;
// 获取加密消息的字节数
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
if(!CryptEncryptMessage(
&EncryptParams,
1,
RecipientCertArray,
orgBlob.pbData,
orgBlob.cbData,
NULL,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Getting encrypted message size failed.");
}
_tprintf(L"The encrypted message is %d bytes. \n",encBlob.cbData);
// 分配空间
encBlob.pbData = (BYTE*) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
delete [] orgBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Memory allocation error while encrypting.");
}
// 加密处理
if(!CryptEncryptMessage(
&EncryptParams,
1,
RecipientCertArray,
orgBlob.pbData,
orgBlob.cbData,
encBlob.pbData,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CryptReleaseContext(hCryptProv, 0);
CancelByError(L"Encrypted message failed.");
}
showData(encBlob.pbData, encBlob.cbData);
if(encFileName != NULL)
{
writeFile(encFileName, encBlob.pbData, encBlob.cbData);
}
// 清理
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
if(hCryptProv != NULL)
{
CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
}
}
// 使用证书私钥解密
void CertDecrypt(LPCSTR encFileName, LPCSTR orgFileName)
{
// 准备数据
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);
// 获取加密者证书
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 设置解密参数
HCERTSTORE CertStoreArray[] = {hCertStore};
CRYPT_DECRYPT_MESSAGE_PARA DecryptParams;
memset(&DecryptParams, 0, sizeof(DecryptParams));
DecryptParams.cbSize = sizeof(DecryptParams);
DecryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
DecryptParams.cCertStore = 1;
DecryptParams.rghCertStore = CertStoreArray;
// 解密
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!CryptDecryptMessage(
&DecryptParams,
encBlob.pbData,
encBlob.cbData,
NULL,
&orgBlob.cbData,
NULL))
{
delete [] encBlob.pbData;
CancelByError(L"Error getting decrypted message size. \n");
}
_tprintf(L"The size for the decrypted message is: %d.\n", orgBlob.cbData);
// 分配空间
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"Memory allocation error while decrypting. \n");
}
// 解密
if(!CryptDecryptMessage(
&DecryptParams,
encBlob.pbData,
encBlob.cbData,
orgBlob.pbData,
&orgBlob.cbData,
NULL))
{
delete [] encBlob.pbData;
delete [] orgBlob.pbData;
CancelByError(L"Decrypted message failed! \n");
}
_tprintf(L"Message Decrypted Successfully. %d\n", orgBlob.cbData);
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
delete [] encBlob.pbData;
delete [] orgBlob.pbData;
}
// 证书加密并签名生成数字信封
void SignAndEncryptData(BYTE * orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 存取证书库
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"The MY store could not be opened.");
}
// 获取签名者证书
PCCERT_CONTEXT pSignerCertContext = NULL;
pSignerCertContext = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pSignerCertContext == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"Signer cert not found.\n");
}
// 获取接收者证书
PCCERT_CONTEXT pReceiverCertContext = NULL;
pReceiverCertContext = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pReceiverCertContext == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"Receiver cert not found.\n");
}
// pReceiverCertContext = pSignerCertContext;
// 申请签名者私钥服务
DWORD dwKeySpec;
HCRYPTPROV hCryptProv;
if(!CryptAcquireCertificatePrivateKey(
pSignerCertContext,
0,
NULL,
&hCryptProv,
&dwKeySpec,
NULL))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"CryptAcquireCertificatePrivateKey.\n");
}
// 设置签名参数
CRYPT_SIGN_MESSAGE_PARA SignPara;
memset(&SignPara, 0, sizeof(SignPara));
SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType = MY_ENCODING_TYPE;
SignPara.pSigningCert = pSignerCertContext ;
SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignPara.HashAlgorithm.Parameters.cbData = 0;
SignPara.pvHashAuxInfo = NULL;
SignPara.cMsgCert = 1;
SignPara.rgpMsgCert = &pSignerCertContext ;
SignPara.cMsgCrl = 0;
SignPara.rgpMsgCrl = NULL;
SignPara.cAuthAttr = 0;
SignPara.rgAuthAttr = NULL;
SignPara.cUnauthAttr = 0;
SignPara.rgUnauthAttr = NULL;
SignPara.dwFlags = 0;
SignPara.dwInnerContentType = 0;
// 设置加密参数
CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara;
memset(&EncryptPara, 0, sizeof(EncryptPara));
EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE;
EncryptPara.hCryptProv = 0;
EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_DES_EDE3_CBC;
EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
EncryptPara.pvEncryptionAuxInfo = NULL;
EncryptPara.dwFlags = 0;
EncryptPara.dwInnerContentType = 0;
// 设置加密的证书
DWORD cRecipientCert;
PCCERT_CONTEXT rgpRecipientCert[5];
cRecipientCert = 1;
rgpRecipientCert[0] = pReceiverCertContext;
// 获取签名并加密消息长度
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
if(!CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
orgBlob.pbData,
orgBlob.cbData,
NULL,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"Getting Signed&Encrypted message length failed.");
}
_tprintf(L"SignAndEncrypte message size is %d bytes.\n", encBlob.cbData);
// 分配空间
encBlob.pbData = (BYTE*) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"Memory allocation error while SignAndEncrypting. \n");
}
// 签名并加密消息
if(!CryptSignAndEncryptMessage(
&SignPara,
&EncryptPara,
cRecipientCert,
rgpRecipientCert,
orgBlob.pbData,
orgBlob.cbData,
encBlob.pbData,
&encBlob.cbData))
{
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
CancelByError(L"The message failed to sign and encrypt.");
}
_tprintf(L"The message is signed and encrypted.\n");
showData(encBlob.pbData, encBlob.cbData);
if(encFileName != NULL)
{
writeFile(encFileName, encBlob.pbData, encBlob.cbData);
}
// 清理
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertFreeCertificateContext(pSignerCertContext);
CertFreeCertificateContext(pReceiverCertContext);
CertCloseStore(hCertStore, 0);
}
// 解密并校验数字信封
void DecryptAndVerifyData(LPCSTR encFileName, LPCSTR orgFileName)
{
// 准备数据
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);
// 存取证书库
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"my");
if(hCertStore == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"The MY store could not be opened.");
}
// 设置解密参数
CRYPT_DECRYPT_MESSAGE_PARA DecryptPara;
memset(&DecryptPara, 0, sizeof(DecryptPara));
DecryptPara.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
DecryptPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
DecryptPara.cCertStore = 1;
DecryptPara.rghCertStore = &hCertStore;
// 设置校验参数
CRYPT_VERIFY_MESSAGE_PARA VerifyPara;
memset(&VerifyPara, 0, sizeof(VerifyPara));
VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyPara.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyPara.hCryptProv = 0;
VerifyPara.pfnGetSignerCertificate = NULL;
VerifyPara.pvGetArg = NULL;
// 获取解密消息长度
DWORD dwSignerIndex = 0;
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
encBlob.pbData,
encBlob.cbData,
NULL,
&orgBlob.cbData,
NULL,
NULL)))
{
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"Get decrypted message size failed.");
}
_tprintf(L"DecryptAndVerify message size is %d bytes.\n", orgBlob.cbData);
// 分配空间
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"Memory allocation error while DecryptAndVerifyMessage. \n");
}
// 解密并校验
PCCERT_CONTEXT pRecverCert;
PCCERT_CONTEXT pSignerCert;
if(!(CryptDecryptAndVerifyMessageSignature(
&DecryptPara,
&VerifyPara,
dwSignerIndex,
encBlob.pbData,
encBlob.cbData,
orgBlob.pbData,
&orgBlob.cbData,
&pRecverCert,
&pSignerCert)))
{
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
CancelByError(L"The message failed to sign and encrypt.");
}
_tprintf(L"The message is decrypted and verifyed.\n");
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
viewCertCN(pSignerCert);
viewCertCN(pRecverCert);
// 清理
delete [] orgBlob.pbData;
delete [] encBlob.pbData;
CertCloseStore(hCertStore, 0);
}
// 加密并签名的数字信封(低级)
void EnvelopeData(BYTE * orgData, int orgSize, LPCSTR orgFileName, LPCSTR encFileName = NULL)
{
// 准备数据
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
prepareData(orgData, orgSize, orgFileName, orgBlob.pbData, orgBlob.cbData);
// 从MY证书库获取签名者证书
HCERTSTORE hCertStore = NULL;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY");
if(hCertStore == NULL)
{
delete [] orgBlob.pbData;
CancelByError(L"Open CertStore failed!\n");
}
// 查找签名者证书
PCCERT_CONTEXT pSignerCert = NULL;
pSignerCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pSignerCert == NULL)
{
delete [] orgBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Signer certificate not found.");
}
_tprintf(L"Signer certificate has been found.\n");
viewCertCN(pSignerCert);
// 申请私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(pSignerCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Acquire certificate privateKey failed!\n");
}
// 设置签名算法
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
memset(&HashAlgorithm, 0, sizeof(HashAlgorithm));
HashAlgorithm.pszObjId = szOID_RSA_MD5;
// 设置签名编码参数
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hKeyProv;
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;
SignerEncodeInfoArray[0] = SignerEncodeInfo;
// 设置签名证书
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
SignerCertBlob.pbData = pSignerCert->pbCertEncoded;
SignerCertBlobArray[0] = SignerCertBlob;
// 设置签名编码参数
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
SignedMsgEncodeInfo.cCrlEncoded = 0;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;
// 获取编码输出的签名块长度
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
sigBlob.cbData = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE,
0,
CMSG_SIGNED,
&SignedMsgEncodeInfo,
NULL,
orgBlob.cbData);
if(sigBlob.cbData == 0)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Getting signed message length failed.");
}
// 分配编码空间
sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
if(sigBlob.pbData == NULL)
{
delete [] orgBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Memory allocation failed. \n");
}
// 编码签名消息
HCRYPTMSG hMsg;
hMsg = CryptMsgOpenToEncode(
MY_ENCODING_TYPE, // encoding type
0, // flags
CMSG_SIGNED, // message type
&SignedMsgEncodeInfo, // pointer to structure
NULL, // inner content OID
NULL); // stream information (not used)
if(hMsg == NULL)
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"The message to be encoded failed. \n");
}
// 添加数据
if(!CryptMsgUpdate(
hMsg, // handle to the message
orgBlob.pbData, // pointer to the content
orgBlob.cbData, // size of the content
TRUE)) // last call
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"CryptMsgUpdate failed.\n");
}
// 获取签名结果
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CONTENT_PARAM, // parameter type
0, // index
sigBlob.pbData, // pointer to the BLOB
&sigBlob.cbData)) // size of the BLOB
{
delete [] orgBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"CryptMsgGetParam signed message failed.\n");
}
// 清理签名部分
delete [] orgBlob.pbData;
if(pSignerCert != NULL)
{
CertFreeCertificateContext(pSignerCert);
pSignerCert = NULL;
}
if(hMsg != NULL)
{
CryptMsgClose(hMsg);
hMsg = NULL;
}
if(hKeyProv != NULL)
{
CryptReleaseContext(hKeyProv, 0);
hKeyProv = NULL;
}
// ----------------------- 签名结束:得到带原文的签名
// 公钥加密
// 查找接收者证书
PCCERT_CONTEXT pRecverCert = NULL;
pRecverCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
L"lny",
NULL);
if(pRecverCert == NULL)
{
delete [] sigBlob.pbData;
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Receiver certificate not found.");
}
_tprintf(L"Receiver certificate has been found.\n");
viewCertCN(pRecverCert);
// 设置加密证书
PCERT_INFO RecipCertArray[1];
RecipCertArray[0] = pRecverCert->pCertInfo;
// 设置加密算法
CRYPT_ALGORITHM_IDENTIFIER ContentEncryptAlgorithm;
memset(&ContentEncryptAlgorithm, 0, sizeof(ContentEncryptAlgorithm));
ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC2CBC;
// 设置信封参数
CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;
memset(&EnvelopedEncodeInfo, 0, sizeof(CMSG_ENVELOPED_ENCODE_INFO));
EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
EnvelopedEncodeInfo.hCryptProv = NULL;
EnvelopedEncodeInfo.ContentEncryptionAlgorithm = ContentEncryptAlgorithm;
EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;
EnvelopedEncodeInfo.cRecipients = 1;
EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;
// 获取消息编码的长度
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
encBlob.cbData = CryptMsgCalculateEncodedLength(
MY_ENCODING_TYPE,
0,
CMSG_ENVELOPED,
&EnvelopedEncodeInfo,
NULL,
sigBlob.cbData);
if(encBlob.cbData == 0)
{
delete [] sigBlob.pbData;
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Getting enveloped cbEncodedBlob length failed.");
}
_tprintf(L"Enveloped message size is %d bytes.", encBlob.cbData);
// 分配编码空间
encBlob.pbData = (BYTE *) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
delete [] sigBlob.pbData;
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Memory allocation failed. \n");
}
// 编码加密
hMsg = CryptMsgOpenToEncode(
MY_ENCODING_TYPE, // encoding type
0, // flags
CMSG_ENVELOPED, // message type
&EnvelopedEncodeInfo, // pointer to structure
NULL, // szOID_RSA_signedData, // inner content OID
NULL);
if(hMsg == NULL)
{
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"The message open to be encode failed. \n");
}
// 添加数据
if(!CryptMsgUpdate(
hMsg, // handle to the message
sigBlob.pbData, // pointer to the content
sigBlob.cbData, // size of the content
TRUE)) // last call
{
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Enveloped CryptMsgUpdate failed.\n");
}
// 获取加密结果
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CONTENT_PARAM, // parameter type
0, // index
encBlob.pbData, // pointer to the BLOB
&encBlob.cbData)) // size of the BLOB
{
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pRecverCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"CryptMsgGetParam enveloped message failed.\n");
}
showData(encBlob.pbData, encBlob.cbData);
if(encFileName != NULL)
{
writeFile(encFileName, encBlob.pbData, encBlob.cbData);
}
// 清理
delete [] encBlob.pbData;
delete [] sigBlob.pbData;
if(hMsg != NULL)
{
CryptMsgClose(hMsg);
hMsg = NULL;
}
if(pRecverCert != NULL)
{
CertFreeCertificateContext(pRecverCert);
pRecverCert = NULL;
}
if(hCertStore != NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
}
// 解密信封并校验签名(低级)
void DevelopeData(LPCSTR encFileName, LPCSTR orgFileName)
{
// 准备数据
CRYPT_DATA_BLOB encBlob;
memset(&encBlob, 0, sizeof(encBlob));
prepareData(NULL, 0, encFileName, encBlob.pbData, encBlob.cbData);
// Open
HCRYPTMSG hMsg = NULL;
hMsg = CryptMsgOpenToDecode(
MY_ENCODING_TYPE, // Encoding type.
0, // Flags.
0, // Use the default message type which is listed in the message header.
NULL, // Cryptographic provider. Use NULL for the default provider.
NULL, // Recipient information.
NULL); // Stream information.
if(hMsg == NULL)
{
delete [] encBlob.pbData;
CancelByError(L"Failed in CryptMsgOpenToDecode.");
}
// Update
if(!CryptMsgUpdate(
hMsg, // Handle to the message
encBlob.pbData, // Pointer to the encoded BLOB
encBlob.cbData, // Size of the encoded BLOB
TRUE))
{
delete [] encBlob.pbData;
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgUpdate.");
}
// 释放加密数据
delete [] encBlob.pbData;
// 开始操作解码后的加密数据 ================================
// 消息类型
DWORD dwType = 0;
DWORD dwSize = sizeof(dwType);
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_TYPE_PARAM, // Parameter type
0, // Index
&dwType, // Buffer
&dwSize)) // Size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_TYPE_PARAM.");
}
// 校验消息类型
if (dwType != CMSG_ENVELOPED)
{
CryptMsgClose(hMsg);
CancelByError(L"Not an enveloped data.");
}
// 消息格式
char szTypeName[1024];
dwSize = 1024;
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_INNER_CONTENT_TYPE_PARAM, // Parameter type
0, // Index
szTypeName, // Buffer
&dwSize)) // Size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_INNER_CONTENT_TYPE_PARAM.");
}
// 检查消息格式
if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0)
{
// CryptMsgClose(hMsg);
// CancelByError(L"The inner content is not szOID_PKCS_7_DATA.");
}
// 获取接收者证书大小
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_RECIPIENT_INFO_PARAM, // Parameter type
0, // Index
NULL, // Buffer
&dwSize)) // Size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_RECIPIENT_INFO_PARAM.");
}
// 分配内存
PCERT_INFO pRecverCertInfo = (PCERT_INFO) new char[dwSize];
if (pRecverCertInfo == NULL)
{
CryptMsgClose(hMsg);
CancelByError(L"Not enough memory.");
}
// 获取接收者证书信息
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_RECIPIENT_INFO_PARAM, // Parameter type
0, // Index
pRecverCertInfo, // Buffer
&dwSize)) // Size of the returned
{
delete [] pRecverCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_RECIPIENT_INFO_PARAM.");
}
// 访问证书库
HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
if(hCertStore == NULL)
{
delete [] pRecverCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Open CertStore failed!\n");
}
// 获取接收者证书
PCCERT_CONTEXT hRcverCertContext = CertGetSubjectCertificateFromStore(hCertStore, MY_ENCODING_TYPE, pRecverCertInfo);
delete [] pRecverCertInfo;
if(hRcverCertContext == NULL)
{
CryptMsgClose(hMsg);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"No matched certificate found in store.");
}
viewCertCN(hRcverCertContext);
// 申请私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
if(!CryptAcquireCertificatePrivateKey(hRcverCertContext, 0, 0, &hCryptProv, &dwKeyType, &bFreeKeyProv))
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Acquire certificate privateKey failed!\n");
}
/**//* ------ 另外一种申请私钥服务的做法:沒验证
bReturn = CertGetCertificateContextProperty(
context,
CERT_KEY_PROV_INFO_PROP_ID ,
NULL,
&dwSize
);
if (!bReturn)
{
CancelByError(L"Failed in CertGetCertificateContextProperty.");
}
CRYPT_KEY_PROV_INFO * key_info = (CRYPT_KEY_PROV_INFO *) malloc (dwSize);
if (!key_info)
CancelByError(L"Not enough memory.");
bReturn = CertGetCertificateContextProperty(
context,
CERT_KEY_PROV_INFO_PROP_ID ,
key_info,
&dwSize
);
if (!bReturn)
{
CancelByError(L"Failed in CertGetCertificateContextProperty.");
}
// acquire a CSP
HCRYPTPROV hCryptProv;
bReturn = CryptAcquireContext(
&hCryptProv, // 返回的句柄
NULL, // CSP key 容器名称
NULL, // CSP 提供者名称
PROV_RSA_FULL, // CSP 提供者类型
0); // 附加参数:
bReturn = CryptAcquireContext(
&hCryptProv,
key_info->pwszContainerName,
key_info->pwszProvName,
key_info->dwProvType,
key_info->dwFlags
);
if (!bReturn)
{
CancelByError(L"Failed in CryptAcquireContext.");
}
*/
// 解密解码的数据
CMSG_CTRL_DECRYPT_PARA para;
para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA);
para.dwKeySpec = dwKeyType;
para.hCryptProv = hCryptProv;
para.dwRecipientIndex = 0;
if(!CryptMsgControl(
hMsg, // Handle to the message
0, // Flags
CMSG_CTRL_DECRYPT, // Control type
¶)) // Pointer to the CERT_INFO
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Failed in CryptMsgControl.");
}
// 获取解密消息大小
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
NULL, //
&sigBlob.cbData)) // Size of the returned
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");
}
// 分配内存
sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
if(sigBlob.pbData == NULL)
{
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Not enough memory.");
}
// 获取解码消息
if(!CryptMsgGetParam(
hMsg, // Handle to the message
CMSG_CONTENT_PARAM, // Parameter type
0, // Index
sigBlob.pbData, //
&sigBlob.cbData)) // Size of the returned
{
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
CancelByError(L"Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");
}
// 清理解密过程数据
CryptMsgClose(hMsg);
CertFreeCertificateContext(hRcverCertContext);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
_tprintf(L"Enveloped message decrypt successfully. \n");
// ----------------------------------- 解密处理完成:得到一个带原文的签名
// 解码带原文的数字签名
hMsg = CryptMsgOpenToDecode(
MY_ENCODING_TYPE, // Encoding type.
0, // Flags.
0, // Use the default message type which is listed in the message header.
NULL, // Cryptographic provider. Use NULL for the default provider.
NULL, // Recipient information.
NULL); // Stream information.
if(hMsg == NULL)
{
delete [] sigBlob.pbData;
CancelByError(L"Failed in CryptMsgOpenToDecode.");
}
// Update
if(!CryptMsgUpdate(
hMsg, // Handle to the message
sigBlob.pbData, // Pointer to the encoded BLOB
sigBlob.cbData, // Size of the encoded BLOB
TRUE))
{
delete [] sigBlob.pbData;
CryptMsgClose(hMsg);
CancelByError(L"Failed in CryptMsgUpdate.");
}
// 释放数字签名数据
delete [] sigBlob.pbData;
// 开始操作解码后的签名数据 ================================
// 获取原文字节数
CRYPT_DATA_BLOB orgBlob;
memset(&orgBlob, 0, sizeof(orgBlob));
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
NULL,
&orgBlob.cbData))
{
CryptMsgClose(hMsg);
CancelByError(L"Get the decoded message failed. \n");
}
_tprintf(L"%d bytes needed for the decoded message.\n", orgBlob.cbData);
// 分配内存
orgBlob.pbData = (BYTE*) new char[orgBlob.cbData];
if(orgBlob.pbData == NULL)
{
CryptMsgClose(hMsg);
CancelByError(L"Not enough memory. \n");
}
// 获取原文
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
orgBlob.pbData,
&orgBlob.cbData))
{
delete [] orgBlob.pbData;
CryptMsgClose(hMsg);
CancelByError(L"Get the decoded message failed. \n");
}
showData(orgBlob.pbData, orgBlob.cbData);
if(orgFileName != NULL)
{
writeFile(orgFileName, orgBlob.pbData, orgBlob.cbData);
}
// 释放原文数据
delete [] orgBlob.pbData;
// 获取签名者证书信息大小
DWORD cbSignerCertInfo;
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CERT_PARAM, // parameter type
0, // index
NULL,
&cbSignerCertInfo)) // size of the returned
{
CryptMsgClose(hMsg);
CancelByError(L"Get SIGNER_CERT_INFO #1 failed.");
}
// 分配内存
BYTE* pSignerCertInfo = (BYTE*) new char[cbSignerCertInfo];
if(pSignerCertInfo == NULL)
{
CryptMsgClose(hMsg);
CancelByError(L"Not enough memory.");
}
// 获取签名者证书信息
if(!CryptMsgGetParam(
hMsg, // handle to the message
CMSG_CERT_PARAM, // parameter type
0, // index
pSignerCertInfo,
&cbSignerCertInfo)) // size of the returned
{
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Get SIGNER_CERT_INFO #1 failed.");
}
// 创建证书上下文
PCCERT_CONTEXT pSignerCertContext = NULL;
pSignerCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE*) pSignerCertInfo, cbSignerCertInfo);
if(pSignerCertContext == NULL)
{
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CancelByError(L"Get Subject Cert failed. ");
}
viewCertCN(pSignerCertContext);
// 校验数字签名
if(!CryptMsgControl(
hMsg,
0,
CMSG_CTRL_VERIFY_SIGNATURE,
pSignerCertContext->pCertInfo))
{
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCertContext);
CancelByError(L"Verify signature failed. \n");
}
_tprintf(L"Verify signature succeeded. \n");
// 清理
delete [] pSignerCertInfo;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pSignerCertContext);
}
int _tmain( int argc, _TCHAR * argv[])
{
// HASH
// hashSHA1((BYTE*)"123456789012345", 15, NULL, "c:\\li.sha1");
// hashSHA1(NULL, 0, "c:\\li.txt", "c:\\li.sha1");
// Encrypt & Decrypt
// DESEncrypt((BYTE*)"12345678", (BYTE*)"XXXXXXXX", (BYTE*)"123456789012345", 15, NULL, "c:\\li.des");
// DESEncrypt((BYTE*)"12345678", (BYTE*)"XXXXXXXX", NULL, 0, "c:\\li.txt", "c:\\li.des");
// AESEncrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", (BYTE*)"123456789012345", 15, NULL, "c:\\li.aes");
// AESEncrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", NULL, 0, "c:\\1.txt", "c:\\li.aes");
// BYTE* pEncData = (BYTE*) "\xCA\x89\x39\xC2\x2F\xB3\x4B\x39\x54\x2e\xd6\xb1\x14\xc9\x31\x10";
// AESDecrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", pEncData, 16, NULL, "c:\\li.org");
// AESDecrypt((BYTE*)"12345678901234561234567890123456", (BYTE*)"XXXXXXXXXXXXXXXX", NULL, 0, "c:\\li.aes", "c:\\1.org");
// CertStore & Cert
// viewSystemCertStore(L"MY");
// viewSystemCertStore(L"CA");
// viewSystemCertStore(L"ROOT");
// viewCrtCertStore(L"c:\\ca\\certs\\lny.crt");
// viewCrtCertStore(L"c:\\cfcaT.p7b");
// viewPfxCertStore("c:\\ca\\lny.pfx", L"welcome2008");
// HASH SignData
// BareSignData((BYTE*) "1234567890", 10, NULL, "c:\\li.sha1.sig");
// VerifyBareSignData((BYTE*) "1234567890", 10, NULL, 0, NULL, "c:\\li.sha1.sig");
// BareSignData(NULL, 0, "c:\\li.txt", "c:\\li.sha1.sig");
// VerifyBareSignData(NULL, 0, NULL, 0, "c:\\li.txt", "c:\\li.sha1.sig");
// TACHED SignData
// SignData((BYTE*)"1234567890", 10, NULL, FALSE, "c:\\li.tch.sig");
// VerifySignedData("c:\\li.tch.sig");
// SignData(NULL, 0, "c:\\li.txt", FALSE, "c:\\li.tch.sig");
// VerifySignedData("c:\\1li.tch.sig", "c:\\li.txt.org");
// DETACHED SignData
// SignData((BYTE*)"1234567890", 10, NULL, TRUE, "c:\\li.detch.sig");
// VerifyDetachedSignData((BYTE*) "1234567890", 10, NULL, "c:\\li.detch.sig");
// VerifyDetachedSignData(NULL, 0, "c:\\li.txt", "c:\\li.detch.sig");
// Cert Encrypt & Decrypt
// CertEncrypt((BYTE*)"1234567890", 10, NULL, "c:\\li.enc");
// CertEncrypt(NULL, 0, "c:\\li.txt", "c:\\li.enc");
// CertDecrypt("c:\\li.enc", "c:\\li.org");
// SignAndEncryptData((BYTE*)"1234567890", 10, NULL, "c:\\li.enc");
// DecryptAndVerifyData("c:\\li.enc", "c:\\li.org");
printf("========================================================================\n");
// Other cert Encrypt & Decrypt (低级消息函数)
// EnvelopeData((BYTE*)"welcome2008WWWWW", 17, NULL, "c:\\li.enc");
DevelopeData("c:\\li.enc", "c:\\li.org");
pause();
return 0;
}