注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.
/*
*
*
* 文件名称:Signer.cpp
* 摘 要:
* 数字签名及验证
* 当前版本:1.0
* 作 者:周绍禹
* 创建日期:2012年3月4日
*/
#include "StdAfx.h"
#include "Signer.h"
#include "Map.h"
#include "generic.h"
#include "base64.h"
Signer::Signer():CSP_NAME(FEITIAN_CSP_NAME)
{
log = new Log("Signer");
certMsg = new CertMsg();
}
Signer::~Signer()
{
if(log) delete log;
if(certMsg) delete certMsg;
}
//-----------------------------------------------------------
// 函数名称:
// sign
// 参数:
// - string plain_text 明文
// - BYTE* target_SN_blob 目标证书的序列号字节数组
// - int cblob 目标证书的序列号字节数组大小
// 返回:
// Result*
// 说明:
// 通过指定的序列号查找证书以及私钥,对数据做数字签名操作
//-----------------------------------------------------------
Result* Signer::sign(string plain_text,BYTE* target_SN_blob,int cblob)
{
// 准备数据
HCRYPTPROV hProv;
if(!CryptAcquireContext(&hProv,
NULL,
CSP_NAME,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
DWORD dwLastErr = GetLastError();
if(NTE_BAD_KEYSET == dwLastErr)
{
Result* result = new Result("Signer.cpp",20,"密钥库不存在,或者访问被拒绝!","{}");
return result;
}
else{
if(!CryptAcquireContext(&hProv,
NULL,
this->CSP_NAME,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
Map* map = new Map(1);
map->put("errcode",dwLastErr);
string errcode = map->toString();
delete map;
Result* result = new Result("Signer.cpp",34,"密钥库已存在,创建密钥库失败!",errcode);
return result;
}
}
}
// 请求证书私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
Result* result = certMsg->acquirePrivateKey(hProv,target_SN_blob,cblob,&hKeyProv,&dwKeyType);
if(!result->isSuccess())
{
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
log->error("Signer.cpp 86 acquirePrivateKey")->error(getErrorCode());
return result;
}
if(hKeyProv==NULL)
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",57,"获取私钥服务失败!",errorcode.length()==0?"{}":errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
log->error("Signer.cpp 86 acquirePrivateKey")->error(errorcode);
return result;
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hKeyProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",73,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 102 CryptCreateHash")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
return result;
}
BYTE *orgTextByte ;
int orgTextLen = plain_text.size();
orgTextByte = new BYTE[orgTextLen + 1];
for(int i=0;i<orgTextLen;i++){
orgTextByte[i]=plain_text[i];
}
orgTextByte[orgTextLen]='\0';
// 计算数据摘要
if(!CryptHashData(hHash, orgTextByte, orgTextLen, 0))
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",94,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 128 CryptHashData")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
return result;
}
DWORD cbSign = 4096;
BYTE *pbSign;
//获取签名数据摘要大小
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",106,"获取签名大小失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 147 CryptSignHash")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
return result;
}
pbSign = new BYTE[cbSign];
//签名数据摘要
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
{
string errorcode = getErrorCode();
Result* result = new Result("Signer.cpp",116,"签名失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 163 CryptSignHash")->error(errorcode);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
if(pbSign) delete[] pbSign;
return result;
}
//将签名值转成base64编码
string baseSign = Base64::base64_encode(pbSign,cbSign);
log->info("----------------------")->info("签名值:")->info(baseSign);
if(hProv != NULL)
CryptReleaseContext(hProv, 0);
if(hKeyProv != NULL)
CryptReleaseContext(hKeyProv, 0);
if(hHash)
CryptDestroyHash(hHash);
if(orgTextByte) delete[] orgTextByte;
if(pbSign) delete[] pbSign;
Result* sign_result = new Result(baseSign);
return sign_result;
}
//-----------------------------------------------------------
// 函数名称:
// verify
// 参数:
// - string signed_text_base64 签名值base64码
// - string cert_base64 数字证书base64码
// - string org_text 明文
// 返回:
// Result*
// 说明:
// 使用传入的证书base64码创建证书上下文,然后使用该证书及其公钥验证数字签名
//-----------------------------------------------------------
Result* Signer::verify(string signed_text_base64,string cert_base64,string org_text)
{
BYTE* signedData;
int length;
signedData = Base64::base64_decode(signed_text_base64,length);
// 请求容器服务
HCRYPTPROV hProv = NULL;
if(!CryptAcquireContext(&hProv,
NULL,
CSP_NAME,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
DWORD dwLastErr = GetLastError();
if(signedData) delete[] signedData;
if(NTE_BAD_KEYSET == dwLastErr)
{
Result* result = new Result("Signer.cpp",164,"密钥库不存在,或者访问被拒绝!","{}");
return result;
}
else{
if(!CryptAcquireContext(&hProv,
NULL,
this->CSP_NAME,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
Map* map = new Map(1);
map->put("errcode",dwLastErr);
string errcode = map->toString();
delete map;
Result* result = new Result("Signer.cpp",178,"密钥库已存在,创建密钥库失败!",errcode);
return result;
}
}
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",196,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 248 CryptCreateHash")->error(errorcode);
if(signedData) delete[] signedData;
if(hProv) CryptReleaseContext(hProv,0);
return result;
}
BYTE* orgBlob;
int orglen = org_text.size();
orgBlob = new BYTE[orglen + 1] ;
for(int i = 0; i < orglen; ++i)
{
orgBlob[i] = (byte)org_text[i];
}
orgBlob[orglen] = '\0';
// 计算数据摘要
if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",216,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 271 CryptHashData")->error(errorcode);
if(signedData) delete[] signedData;
if(hProv) CryptReleaseContext(hProv,0);
if(orgBlob) delete[] orgBlob;
if(hHash) CryptDestroyHash(hHash);
return result;
}
// 获取签名者证书公钥
BYTE* cert;
int len;
cert = Base64::base64_decode(cert_base64,len);
char* len_log_str = new char[20];
itoa(len,len_log_str,10);
log->info("-----------------------")->info("Signer.cpp 290 CertCreateCertificateContext")->info(cert_base64)->info(len_log_str);
PCCERT_CONTEXT pCertContext = NULL;
pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
cert,
len) ;
if(pCertContext == NULL)
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",238,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 290 CertCreateCertificateContext")->error(errorcode);
if(signedData) delete[] signedData;
if(hProv) CryptReleaseContext(hProv,0);
if(orgBlob) delete[] orgBlob;
if(hHash) CryptDestroyHash(hHash);
if(cert) delete[] cert;
return result;
}
//获取公钥句柄
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",250,"导入公钥失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 308 CryptImportPublicKeyInfo")->error(errorcode);
if(signedData) delete[] signedData;
if(hProv) CryptReleaseContext(hProv,0);
if(orgBlob) delete[] orgBlob;
if(hHash) CryptDestroyHash(hHash);
if(cert) delete[] cert;
if(pCertContext) CryptReleaseContext(hProv,0);
return result;
}
//验证签名
if(!CryptVerifySignature(hHash, signedData, length, hPubKey, NULL, 0))
{
string errorcode = getErrorCode();
Result* result = new Result("Singer.cpp",257,"验证签名失败!",errorcode.length()==0?"{}":errorcode);
log->error("Signer.cpp 322 CryptVerifySignature")->error(errorcode);
if(signedData) delete[] signedData;
if(hProv) CryptReleaseContext(hProv,0);
if(orgBlob) delete[] orgBlob;
if(hHash) CryptDestroyHash(hHash);
if(cert) delete[] cert;
if(pCertContext) CertFreeCertificateContext(pCertContext);
if(hPubKey) CryptDestroyKey(hPubKey);
return result;
}
//释放内存
if(signedData) delete[] signedData;
if(hProv) CryptReleaseContext(hProv,0);
if(orgBlob) delete[] orgBlob;
if(hHash) CryptDestroyHash(hHash);
if(cert) delete[] cert;
if(pCertContext) CertFreeCertificateContext(pCertContext);
if(hPubKey) CryptDestroyKey(hPubKey);
Result* result = new Result(org_text);
return result;
}
-------------------------改版分割线---------------------------------------------
以下代码只做示例,还存在许多问题需要修改
签名与验证(分验证证书合法性与不验证证书两种验证签名)
签名与验证(分验证证书合法性与不验证证书两种验证签名)
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#include <iostream>
#include "Base.h" //实现Base64转码
#include <comdef.h>
using namespace std;
#define TEST_CSP_NAME "FEITIAN ePassNG RSA Cryptographic Service Provider" //飞天CSP
//返回值为'签名base64码'和';'和'证书base64码'
STDMETHODIMP CSignedData::Sign(BSTR orgData, BSTR* signature)
{
// TODO: Add your implementation code here
string orgText = _bstr_t (orgData);
// 准备数据
HCRYPTPROV hProv;
// --------------------------------------------------------------------
// get the CSP handle
printf("The following phase of this program is signature.\n\n");
if(CryptAcquireContext(
&hProv,
NULL,
TEST_CSP_NAME,
PROV_RSA_FULL,
0))
{
printf("CSP context acquired.\n");
}
else //create if not exist
{
if(CryptAcquireContext(
&hProv,
NULL,
TEST_CSP_NAME,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
printf("A new key container has been created.\n");
}
else
{
}
}
// 打开证书库
HCERTSTORE hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM, // The store provider type.
0, // The encoding type is not needed.
hProv, // Use the epassNG HCRYPTPROV.
CERT_SYSTEM_STORE_CURRENT_USER,
L"MY"
);
if(hCertStore == NULL)
{
}
// 查找证书
PCCERT_CONTEXT hCert = CertFindCertificateInStore(
hCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_STR,
L"周绍禹",
NULL);
if(hCert == NULL)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
return E_FAIL;
}
/**//*
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))
{
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hKeyProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
BYTE *orgTextByte ;
int orgTextLen = orgText.size();
orgTextByte = new BYTE[orgTextLen];
for(int i=0;i<orgTextLen;i++){
orgTextByte[i]=orgText[i];
}
orgTextByte[orgTextLen]='\0';
// 计算数据摘要
if(CryptHashData(hHash, orgTextByte, orgTextLen, 0) == 0)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
/**//*
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;
//获取签名数据摘要大小
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
pbSign = new BYTE[cbSign];
//签名数据摘要
if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
{
CryptDestroyHash(hHash);
CryptReleaseContext(hKeyProv, 0);
CertFreeCertificateContext(hCert);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
cout<<base64_encode(pbSign,cbSign)<<endl;
//将签名值转成base64编码
string baseSign = base64_encode(pbSign,cbSign);
//获取证书的base64编码
BYTE *newCert;
newCert = new BYTE[hCert->cbCertEncoded];
newCert = hCert->pbCertEncoded;
string baseCert = base64_encode(newCert,hCert->cbCertEncoded);
//返回签名和证书的base64编码
CComBSTR bstr((baseSign+";"+baseCert).c_str());
*signature=bstr;
//释放资源
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;
}
return S_OK;
}
//验证签名(无证书验证)
STDMETHODIMP CSignedData::VerifySign(BSTR Signed_base64, BSTR Cert_base64, BSTR orgData, BOOL* verifySuc)
{
// TODO: Add your implementation code here
// 准备数据
BYTE* signedData;
string cstrSigned = _bstr_t (Signed_base64);
string decodeData = base64_decode(cstrSigned);
int len = decodeData.size();
signedData = new BYTE[len] ;
for(int i = 0; i < len; ++i)
{
signedData[i] = (byte)decodeData[i];
}
signedData[len] = '\0';
// 请求容器服务
HCRYPTPROV hProv = NULL;
if(!CryptAcquireContext(
&hProv, // 返回的句柄
NULL, // CSP key 容器名称
TEST_CSP_NAME, // CSP 提供者名称
PROV_RSA_FULL, // CSP 提供者类型
0)) // 附加参数
{
return E_FAIL;
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
CryptReleaseContext(hProv, 0);
return E_FAIL;
}
string cstrOrgData = _bstr_t (orgData);
BYTE* orgBlob;
int orglen = cstrOrgData.size();
orgBlob = new BYTE[orglen] ;
for(int i = 0; i < orglen; ++i)
{
orgBlob[i] = (byte)cstrOrgData[i];
}
orgBlob[orglen] = '\0';
// 计算数据摘要
if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return E_FAIL;
}
// 获取签名者证书公钥
/*
HCERTSTORE WINAPI CertOpenStore(
__in LPCSTR lpszStoreProvider,
__in DWORD dwMsgAndCertEncodingType,
__in HCRYPTPROV_LEGACY hCryptProv,
__in DWORD dwFlags,
__in const void* pvPara
);
*/
BYTE* cert;
string cstrCert_base64 = _bstr_t (Cert_base64);
string decodeCert = base64_decode(cstrCert_base64);
int certLen = decodeCert.size();
cert = new BYTE[certLen] ;
for(int i = 0; i < certLen; ++i)
{
cert[i] = (byte)decodeCert[i];
}
cert[certLen] = '\0';
PCCERT_CONTEXT pCertContext = NULL;
if(pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // The encoding type
cert, // The encoded data from
// the certificate retrieved
certLen)) // The length of the encoded data
{
printf("A new certificate has been created.\n");
// Use the certificate context as needed.
// ...
}
else
{
printf("A new certificate could not be created.\n");
return E_FAIL;
}
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
CryptDestroyKey(hPubKey);
CryptReleaseContext(hProv, 0);
return E_FAIL;
}
// 校验签名
/*
BOOL WINAPI CryptVerifySignature(
__in HCRYPTHASH hHash,
__in BYTE* pbSignature,
__in DWORD dwSigLen,
__in HCRYPTKEY hPubKey,
__in LPCTSTR sDescription,
__in DWORD dwFlags
);
*/
if(!CryptVerifySignature(hHash, signedData, len, hPubKey, NULL, 0))
{
*verifySuc=false;
return S_FALSE;
}
else
{
*verifySuc=true;
}
// 释放获取的对象
if(hPubKey != NULL)
{
CryptDestroyKey(hPubKey);
hPubKey = NULL;
}
if(hHash != NULL)
{
CryptDestroyHash(hHash);
hHash = NULL;
}
if(pCertContext != NULL)
{
CertFreeCertificateContext(pCertContext);
pCertContext = NULL;
}
if(hProv != NULL)
{
CryptReleaseContext(hProv, 0);
hProv = NULL;
}
return S_OK;
}
//带证书验证部分的签名验证
STDMETHODIMP CSignedData::VerifySignWithCRL(BSTR Signed_base64, BSTR Cert_base64, BSTR orgData, BSTR CRL_base64, BOOL* verifySuc)
{
// TODO: 在此添加实现代码
// TODO: Add your implementation code here
// 准备数据
BYTE* signedData;
string cstrSigned = _bstr_t (Signed_base64);
string cstrCRL_base64 = _bstr_t(CRL_base64);
int count = cstrCRL_base64.size();
string decodeData = base64_decode(cstrSigned);
int len = decodeData.size();
signedData = new BYTE[len] ;
for(int i = 0; i < len; ++i)
{
signedData[i] = (byte)decodeData[i];
}
signedData[len] = '\0';
// 请求容器服务
HCRYPTPROV hProv = NULL;
if(!CryptAcquireContext(
&hProv, // 返回的句柄
NULL, // CSP key 容器名称
TEST_CSP_NAME, // CSP 提供者名称
PROV_RSA_FULL, // CSP 提供者类型
0)) // 附加参数
{
return E_FAIL;
}
// 创建离散对象
HCRYPTHASH hHash = NULL;
if(!CryptCreateHash(
hProv, // 容器句柄
CALG_MD5, // 算法标识
NULL, // 算法使用的Key
0, // 算法标识
&hHash)) // 返回的HASH对象
{
CryptReleaseContext(hProv, 0);
return E_FAIL;
}
string cstrOrgData = _bstr_t (orgData);
BYTE* orgBlob;
int orglen = cstrOrgData.size();
orgBlob = new BYTE[orglen] ;
for(int i = 0; i < orglen; ++i)
{
orgBlob[i] = (byte)cstrOrgData[i];
}
orgBlob[orglen] = '\0';
// 计算数据摘要
if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return E_FAIL;
}
// 获取签名者证书公钥
/*
HCERTSTORE WINAPI CertOpenStore(
__in LPCSTR lpszStoreProvider,
__in DWORD dwMsgAndCertEncodingType,
__in HCRYPTPROV_LEGACY hCryptProv,
__in DWORD dwFlags,
__in const void* pvPara
);
*/
BYTE* cert;
string cstrCert_base64 = _bstr_t (Cert_base64);
string decodeCert = base64_decode(cstrCert_base64);
int certLen = decodeCert.size();
cert = new BYTE[certLen] ;
for(int i = 0; i < certLen; ++i)
{
cert[i] = (byte)decodeCert[i];
}
cert[certLen] = '\0';
PCCERT_CONTEXT pCertContext = NULL;
if(pCertContext = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // The encoding type
cert, // The encoded data from
// the certificate retrieved
certLen)) // The length of the encoded data
{
printf("A new certificate has been created.\n");
// Use the certificate context as needed.
// ...
}
else
{
printf("A new certificate could not be created.\n");
return E_FAIL;
}
bool certIsValid = verifyCert(pCertContext,cstrCRL_base64);
if(certIsValid){
HCRYPTKEY hPubKey;
if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
{
CryptDestroyKey(hPubKey);
CryptReleaseContext(hProv, 0);
return E_FAIL;
}
// 校验签名
/*
BOOL WINAPI CryptVerifySignature(
__in HCRYPTHASH hHash,
__in BYTE* pbSignature,
__in DWORD dwSigLen,
__in HCRYPTKEY hPubKey,
__in LPCTSTR sDescription,
__in DWORD dwFlags
);
*/
if(!CryptVerifySignature(hHash, signedData, len, hPubKey, NULL, 0))
{
*verifySuc=false;
return S_FALSE;
}
else
{
*verifySuc=true;
}
if(hPubKey != NULL)
{
CryptDestroyKey(hPubKey);
hPubKey = NULL;
}
}else{
*verifySuc=false;
}
// 释放获取的对象
if(hHash != NULL)
{
CryptDestroyHash(hHash);
hHash = NULL;
}
if(pCertContext != NULL)
{
CertFreeCertificateContext(pCertContext);
pCertContext = NULL;
}
if(hProv != NULL)
{
CryptReleaseContext(hProv, 0);
hProv = NULL;
}
return S_OK;
}
// 校验证书合法性
bool verifyCert(PCCERT_CONTEXT hCert,string CRL_base64)
{
/*
*获取CRLContext对象
*/
string CRL = base64_decode(CRL_base64);
BYTE *pbCRL = NULL;
pbCRL = new BYTE[CRL.size()];
for(int i=0;i<CRL.size();i++){
pbCRL[i]=(BYTE)CRL[i];
}
int cbCRL = CRL.size();
pbCRL[cbCRL]='\0';
PCCRL_CONTEXT hCRL = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pbCRL,cbCRL);
if(hCRL==NULL){
printf("未找到CRL");
}else{
printf("找到CRL");
}
/**//*
LONG WINAPI CertVerifyTimeValidity(
__in LPFILETIME pTimeToVerify,
__in PCERT_INFO pCertInfo
);
*/
// 校验证书日期
int nRetCode = CertVerifyTimeValidity(NULL, hCert->pCertInfo);
if(nRetCode < 0)
{
printf("Verify cert's date failed: BEFORE date after TODAY!\n");
return false;
}
if(nRetCode > 0)
{
printf("Verify cert's date failed: Cert has expired!\n");
return false;
}
if(nRetCode == 0)
{
printf("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)
{
printf("Verify cert by issuser's cert succeed! \n");
bCheckOK = TRUE;
break;
}
}
else
{
printf("Verify cert by issuser's cert failed! \n");
return false;
break;
}
// Next ..
hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, hIssuserCert, &dwFlags);
}
if(!bCheckOK)
{
printf("Verify cert by issuser's cert failed! \n");
return false;
}
}
else
{
printf("Can not find cert issuser's cert!\n");
}
if(hIssuserCert != NULL)
{
CertFreeCertificateContext(hIssuserCert);
hIssuserCert = NULL;
}
}
else
{
printf("Open ROOT CertStore failed!\n");
return false;
}
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))
{
printf("CRL is valid for the cert!\n");
}
else
{
printf("CRL is invalid for the cert!!\n");
return false;
}
/**//*
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)
{
printf("Cert has been revoked!\n");
return false;
}
else
{
printf("Cert not be revoked!\n");
}
}
else
{
printf("Find cert in CRL failed!\n");
return false;
}
}
else
{
printf("Create CRL context failed!\n");
return false;
}
if(hCRL != NULL)
{
CertFreeCRLContext(hCRL);
}
}