编写ATL工程实现ActiveX控件调用cryptoAPI接口(二)------------信封加密与解密
注:下面的代码中用了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;
- }
编写ATL工程实现ActiveX控件调用cryptoAPI接口(二)------------信封加密与解密相关推荐
- 编写ATL工程实现ActiveX控件调用cryptoAPI接口(三)------------AES对称加密与解密
注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出. [cpp] view plain copy print ? /* * * * 文件名称:Enc ...
- 编写ATL工程实现ActiveX控件调用cryptoAPI接口(一)------------签名与验证
注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出. [cpp] view plain copy print ? /* * * * 文件名称:Sig ...
- 使用ATL创建简单ActiveX控件(一) —— 创建ATL项目
创建过程以VS2010为例,分三篇(创建ATL项目.添加方法/属性和枚举.添加连接点)演示.本篇演示创建ATL项目. 传送门: <使用ATL创建简单ActiveX控件(二) -- 添加方法/属性 ...
- 如何在VB中实现ActiveX控件的IobjectSafety接口
如何在VB中实现ActiveX控件的IobjectSafety接口 ------------------------------------------------------------------ ...
- ActiveX控件开发总结(续二)
开发过程中一些经验总结 以下总结主要由李俊峰(lijunfeng 00165774/huawei,).李伟(liwei 00165242/huawei,).姜川(j00132245)总结 1.自定义C ...
- 关于vlc播放器的ActiveX控件调用问题
下了好几个版本的vlc播放器,却发现vlc播放器自带的ActiveX插件除了初始化能用之外,后面的js接口完全用不了 从1.0.5版本之后的ActiveX无法调用第一版的js接口 从2.0.5版本之后 ...
- 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题
程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...
- VS创建ATL项目,ActiveX控件
1. 前言 最近一直在做浏览器控件相关,面向IE浏览器.虽然IE有各种缺点,但是还是有很多项目是基于IE的.呃呃呃,比如需要与硬件交互,可以需要多个控件配合,最起码我遇到了(签名控件VCTK和一些远程 ...
- [转]ASP中ActiveX控件的内嵌及调用
懂ASP(Active Server Pages)的人很多,但能用ASP自如地调用ActiveX控件的人却不多:如果不调用ActiveX控件,则可以说微软当初设计ASP的初衷根本没有达到.众所周知,A ...
最新文章
- SEH反调试(SetUnhandledExceptionFilter)
- 【数字图像处理】Canny边缘检测详解及编程实现
- 【前端】VUE UI的安装
- linux安装oracle
- video safari不支持吗_您支持吗? 公园遛狗纳入 “不文明行为黑名单”
- 第八周项目4-个人所得税计算器
- html字体兼容写法,字体兼容写法
- wps日期加减算天数_日期相减之后的天数怎么用公式计算 - 卡饭网
- Spartan-6 FPGA 如何使用ISE下载程序
- java 表头固定_常用的固定表头的几种做法
- linux硬链接与软链接的联系与区别
- vue后端模板、vue登录界面、注册界面(带短信验证码)模板
- 开发基于地图的火车站点查询系统
- 怎样给电脑文件夹批量快速重新命名?
- C++ 汇编代码分析——递归函数调用、浮点数比较、选择语句
- Educational Codeforces Round 40千名记
- 微信小程序输入框input
- Bootstrap-30分钟就能上手的Bootstrap教程【史上最全】
- 宿命之战:程序员VS产品经理
- kafka删除队列_Kafka消息队列
热门文章
- 华为荣耀note10计算机在哪找,华为荣耀note10如何使用电脑模式-华为云电脑使用方法介绍 - Iefans...
- 乐信季报图解:交易额达562亿 利润4.1亿环比增长59%
- Leetcode刷题笔记——剑指 Offer 46. 把数字翻译成字符串(中等)
- 官宣 加速科技与思特威联合开发高速图像采集测试系统
- 上了 istio 的贼船之 API Gateway
- 20190912-1 每周例行报告
- 【Why】物理内存与虚拟内存区别与联系
- #define xxx后面啥都不跟是什么意思
- ajax的常用api测试
- 核查清单-小程序分享功能