注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.
/*
*
*
* 文件名称:Envelop.cpp
* 摘 要:
* 数字信封加密与解密
* 当前版本:1.0
* 作 者:周绍禹
* 创建日期:2012年3月4日
*/
#include "StdAfx.h"
#include "Envelop.h"
#include "base64.h"
#include "Map.h"
#include <sstream>
#include "generic.h"
Envelop::Envelop():CSP_NAME(FEITIAN_CSP_NAME)
{
log = new Log("Envelop");
certMsg = new CertMsg();
}
Envelop::~Envelop()
{
delete log;
delete certMsg;
}
//-----------------------------------------------------------
// 函数名称:
// envelop
// 参数:
// - string recCert_base64 用作非对称加密的公钥所对应的证书base64码
// - string cipher_key_base64 信封加密的目标base64(在项目中也就是对称密钥)
// 返回:
// Result*
// 说明:
// 会将目标base64码解码,后对得到的二进制数组进行信封加密
// 成功返回的为包含加密完成的信封base64码,或者返回异常信息
//-----------------------------------------------------------
Result* Envelop::envelop(string recCert_base64, string cipher_key_base64)
{
// 公钥加密
//获取证书
BYTE* rec_cert;
int length;
rec_cert = Base64::base64_decode(recCert_base64,length);
int cipher_size;
BYTE* msgContent = Base64::base64_decode(cipher_key_base64,cipher_size);
PCCERT_CONTEXT pRecverCert = NULL;
if(!(pRecverCert = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
rec_cert,
length)))
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",42,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 45 CertCreateCertificateContext")->error(errorcode);
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
return result;
}
// 设置加密证书
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(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CMSG_ENVELOPED,
&EnvelopedEncodeInfo,
NULL,
cipher_size);
if(encBlob.cbData == 0)
{
CertFreeCertificateContext(pRecverCert);
log->error("Envelop.cpp 85 CryptMsgCalculateEncodedLength")->error(getErrorCode());
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",79,"获取信封块大小失败!",errorcode.length()==0?"{}":errorcode);
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
if(pRecverCert) CertFreeCertificateContext(pRecverCert);
return result;
}
// 分配编码空间
encBlob.pbData = (BYTE *) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",107,"分配编码空间失败!",errorcode.length()==0?"{}":errorcode);
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
if(pRecverCert) CertFreeCertificateContext(pRecverCert);
return result;
}
HCRYPTMSG hMsg;
// 编码加密
hMsg = CryptMsgOpenToEncode(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CMSG_ENVELOPED,
&EnvelopedEncodeInfo,
NULL,
NULL);
if(hMsg == NULL)
{
string errorcode = getErrorCode();
log->error("Envelop.cpp 119 CryptMsgOpenToEncode")->error(errorcode);
Result* result = new Result("Envelop.cpp",117,"获取信封块大小失败!",errorcode.length()==0?"{}":errorcode);
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
if(pRecverCert) CertFreeCertificateContext(pRecverCert);
return result;
}
// 添加数据
if(!CryptMsgUpdate(
hMsg,
msgContent,
cipher_size,
TRUE))
{
string errorcode = getErrorCode();
log->error("Envelop.cpp 138 CryptMsgUpdate")->error(errorcode);
Result* result = new Result("Envelop.cpp",141,"添加数据失败!",errorcode.length()==0?"{}":errorcode);
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
if(pRecverCert) CertFreeCertificateContext(pRecverCert);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
// 获取加密结果
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
encBlob.pbData,
&encBlob.cbData))
{
string errorcode = getErrorCode();
log->error("Envelop.cpp 156 CryptMsgGetParam")->error(errorcode);
Result* result = new Result("Envelop.cpp",157,"获得加密失败!",errorcode.length()==0?"{}":errorcode);
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
if(pRecverCert) CertFreeCertificateContext(pRecverCert);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
string baseEnc = Base64::base64_encode(encBlob.pbData,encBlob.cbData);
// 清理
if(rec_cert) delete[] rec_cert;
if(msgContent) delete[] msgContent;
if(encBlob.pbData) delete [] encBlob.pbData;
if(hMsg != NULL)
CryptMsgClose(hMsg);
if(pRecverCert != NULL)
CertFreeCertificateContext(pRecverCert);
Result* result = new Result(baseEnc);
return result;
}
//-----------------------------------------------------------
// 函数名称:
// develop
// 参数:
// - string env_base64 加密的信封base64码
// - BYTE* target_SN_blob 用来解密的数字证书序列号字节数组
// - int cblob 用来解密的数字证书序列号字节数组大小
// 返回:
// Result*
// 说明:
// 通过序列号查找到用来解密的证书,并获取私钥用作解密信封
// 成功返回的为包含目标的base64码(即对称密钥的Base64码),或者异常信息
//-----------------------------------------------------------
Result* Envelop::develop(string enc_base64,BYTE* target_SN_blob,int cblob)
{
int encLen;
BYTE* encBYTE;
encBYTE = Base64::base64_decode(enc_base64,encLen);
HCRYPTPROV hProv;
if(!CryptAcquireContext(&hProv,
NULL,
CSP_NAME,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
DWORD dwLastErr = GetLastError();
if(encBYTE) delete[] encBYTE;
if(NTE_BAD_KEYSET == dwLastErr)
{
Result* result = new Result("Envelop.cpp",202,"密钥库不存在,或者访问被拒绝!","{}");
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("Envelop.cpp",216,"密钥库已存在,创建密钥库失败!",errcode);
return result;
}
}
}
HCRYPTMSG hMsg = NULL;
hMsg = CryptMsgOpenToDecode(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
0,
NULL,
NULL,
NULL);
if(hMsg == NULL)
{
string errorcode = getErrorCode();
log->error("Envelop.cpp 239 CryptMsgOpenToDecode")->error(errorcode);
Result* result = new Result("Envelop.cpp",239,"获取解码句柄失败!",errorcode.length()==0?"{}":errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
return result;
}
if(!CryptMsgUpdate(
hMsg,
encBYTE,
encLen + 1,
TRUE))
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",247,"解码失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 257 CryptMsgUpdate")->error(errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
// 消息类型
DWORD dwType = 0;
DWORD dwSize = sizeof(dwType);
if(!CryptMsgGetParam(
hMsg,
CMSG_TYPE_PARAM,
0,
&dwType,
&dwSize))
{
CryptMsgClose(hMsg);
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",263,"解码失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 276 CryptMsgGetParam")->error(errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
// 校验消息类型
if (dwType != CMSG_ENVELOPED)
{
Result* result = new Result("Envelop.cpp",274,"消息类型错误!","{}");
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
// 消息格式
char szTypeName[1024];
dwSize = 1024;
if(!CryptMsgGetParam(
hMsg,
CMSG_INNER_CONTENT_TYPE_PARAM,
0,
szTypeName,
&dwSize))
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",287,"获取消息格式失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 306 CryptMsgGetParam")->error(errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
// 检查消息格式
if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0)
{
Result* result = new Result("Envelop.cpp",287,"消息格式错误!","{}");
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
// 请求证书私钥服务
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
DWORD dwKeyType = 0;
BOOL bFreeKeyProv = FALSE;
Result* result_privateKey = certMsg->acquirePrivateKey(hProv,target_SN_blob,cblob,&hKeyProv,&dwKeyType);
if(!result_privateKey->isSuccess())
{
log->error("Envelop.cpp 338 acquirePrivateKey");
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
if(hKeyProv) CryptReleaseContext(hKeyProv, 0);
return result_privateKey;
}
if(hKeyProv==NULL)
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",316,"获取私钥服务失败!",errorcode.length()==0?"{}":errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
return result;
}
CMSG_CTRL_DECRYPT_PARA para;
para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA);
para.dwKeySpec = dwKeyType;
para.hCryptProv = hKeyProv;
para.dwRecipientIndex = 0;
if(!CryptMsgControl(
hMsg,
0,
CMSG_CTRL_DECRYPT,
¶))
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",335,"解密控制失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 364 CryptMsgControl")->error(errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
if(hKeyProv) CryptReleaseContext(hKeyProv, 0);
return result;
}
// 获取解密消息大小
CRYPT_DATA_BLOB sigBlob;
memset(&sigBlob, 0, sizeof(sigBlob));
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
NULL,
&sigBlob.cbData))
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",351,"获取解密消息大小失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 382 CryptMsgGetParam")->error(errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
if(hKeyProv) CryptReleaseContext(hKeyProv, 0);
return result;
}
// 分配内存
sigBlob.pbData = new BYTE[sigBlob.cbData];
if(sigBlob.pbData == NULL)
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",366,"分配内存空间失败!",errorcode.length()==0?"{}":errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
if(hKeyProv) CryptReleaseContext(hKeyProv, 0);
return result;
}
// 获取解码消息
if(!CryptMsgGetParam(
hMsg,
CMSG_CONTENT_PARAM,
0,
sigBlob.pbData,
&sigBlob.cbData))
{
string errorcode = getErrorCode();
Result* result = new Result("Envelop.cpp",377,"获取解码消息失败!",errorcode.length()==0?"{}":errorcode);
log->error("Envelop.cpp 411 CryptMsgGetParam")->error(errorcode);
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
if(hKeyProv) CryptReleaseContext(hKeyProv, 0);
return result;
}
sigBlob.pbData[sigBlob.cbData]='\0';
// 清理解密过程数据
if(encBYTE) delete[] encBYTE;
if(hProv) CryptReleaseContext(hProv, 0);
if(hMsg) CryptMsgClose(hMsg);
if(hKeyProv) CryptReleaseContext(hKeyProv, 0);
string text = Base64::base64_encode(sigBlob.pbData,sigBlob.cbData);
Result* result = new Result(text);
return result;
}
------------------------------下面为刚接触的版本,上面为修改后的版本--------------------------
代码有待修改
信封加密与解密
#include "Base.h" //Base64转码
#include <comdef.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <wincrypt.h>
#include <iostream>
using namespace std;
#define TEST_CSP_NAME "FEITIAN ePassNG RSA Cryptographic Service Provider" //飞天CSP
//加密信封
STDMETHODIMP CEnvelop::Envelop(BSTR recCert_base64_bstr, BSTR plainText_bstr, BSTR* envelopedData)
{
string recCert_base64 = _bstr_t(recCert_base64_bstr);
string plainText = _bstr_t(plainText_bstr);
// TODO: Add your implementation code here
// 公钥加密
//获取证书
BYTE* rec_cert;
string rec_cstrCert_base64 = recCert_base64;
string rec_decodeCert = base64_decode(rec_cstrCert_base64);
int rec_certLen = rec_decodeCert.size();
rec_cert = new BYTE[rec_certLen] ;
for(int i = 0; i < rec_certLen; ++i)
{
rec_cert[i] = (byte)rec_decodeCert[i];
}
rec_cert[rec_certLen] = '\0';
PCCERT_CONTEXT pRecverCert = NULL;
if(pRecverCert = CertCreateCertificateContext(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // The encoding type
rec_cert, // The encoded data from
// the certificate retrieved
rec_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");
}
// 设置加密证书
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(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CMSG_ENVELOPED,
&EnvelopedEncodeInfo,
NULL,
plainText.size());
if(encBlob.cbData == 0)
{
CertFreeCertificateContext(pRecverCert);
printf("Getting enveloped cbEncodedBlob length failed.");
}
printf("Enveloped message size is %d bytes.", encBlob.cbData);
// 分配编码空间
encBlob.pbData = (BYTE *) new char[encBlob.cbData];
if(encBlob.pbData == NULL)
{
CertFreeCertificateContext(pRecverCert);
printf("Memory allocation failed. \n");
}
HCRYPTMSG hMsg;
// 编码加密
hMsg = CryptMsgOpenToEncode(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // 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;
CertFreeCertificateContext(pRecverCert);
printf("The message open to be encode failed. \n");
}
BYTE* msgContent;
int size = plainText.size();
msgContent = new BYTE[size];
for(int i=0;i<size;i++){
msgContent[i]=(BYTE)plainText[i];
}
msgContent[size]='\0';
// 添加数据
if(!CryptMsgUpdate(
hMsg, // handle to the message
msgContent, // pointer to the content
size, // size of the content
TRUE)) // last call
{
delete [] encBlob.pbData;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pRecverCert);
printf("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;
CryptMsgClose(hMsg);
CertFreeCertificateContext(pRecverCert);
printf("CryptMsgGetParam enveloped message failed.\n");
}
string baseEnc = base64_encode(encBlob.pbData,encBlob.cbData);
// 清理
delete [] encBlob.pbData;
if(hMsg != NULL)
{
CryptMsgClose(hMsg);
hMsg = NULL;
}
if(pRecverCert != NULL)
{
CertFreeCertificateContext(pRecverCert);
pRecverCert = NULL;
}
CComBSTR bstr(baseEnc.c_str());
*envelopedData = bstr;
return S_OK;
}
//解密信封
STDMETHODIMP CEnvelop::Develop(BSTR enc_base64_bstr, BSTR* plainText)
{
string enc_base64 = _bstr_t(enc_base64_bstr);
// TODO: Add your implementation code here
string enc = base64_decode(enc_base64);
int encLen = enc.size();
BYTE* encBYTE;
encBYTE = new BYTE[encLen];
for(int i=0;i<encLen;i++){
encBYTE[i]=enc[i];
}
encBYTE[encLen]='\0';
// 准备数据
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
{
}
}
// Open
HCRYPTMSG hMsg = NULL;
hMsg = CryptMsgOpenToDecode(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // 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)
{
printf("Failed in CryptMsgOpenToDecode.");
}
// Update
if(!CryptMsgUpdate(
hMsg, // Handle to the message
encBYTE, // Pointer to the encoded BLOB
encLen, // Size of the encoded BLOB
TRUE))
{
CryptMsgClose(hMsg);
printf("Failed in CryptMsgUpdate.");
}
// 开始操作解码后的加密数据 ================================
// 消息类型
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);
printf("Failed in CryptMsgGetParam for CMSG_TYPE_PARAM.");
}
// 校验消息类型
if (dwType != CMSG_ENVELOPED)
{
CryptMsgClose(hMsg);
printf("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);
printf("Failed in CryptMsgGetParam for CMSG_INNER_CONTENT_TYPE_PARAM.");
}
// 检查消息格式
if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0)
{
// CryptMsgClose(hMsg);
// printf("The inner content is not szOID_PKCS_7_DATA.");
}
// 打开证书库
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);
}
/**//*
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);
}
CMSG_CTRL_DECRYPT_PARA para;
para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA);
para.dwKeySpec = dwKeyType;
para.hCryptProv = hProv;
para.dwRecipientIndex = 0;
if(!CryptMsgControl(
hMsg, // Handle to the message
0, // Flags
CMSG_CTRL_DECRYPT, // Control type
¶)) // Pointer to the CERT_INFO
{
CryptMsgClose(hMsg);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
printf("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);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
printf("Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");
}
// 分配内存
sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];
if(sigBlob.pbData == NULL)
{
CryptMsgClose(hMsg);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
printf("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);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
printf("Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");
}
sigBlob.pbData[sigBlob.cbData]='\0';
// 清理解密过程数据
CryptMsgClose(hMsg);
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
printf("Enveloped message decrypt successfully. \n");
char* text = (char*)sigBlob.pbData;
CComBSTR bstr(text);
*plainText = bstr;
return S_OK;
}