编写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;
	}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值