/* * * * 文件名称: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; }