编写ATL工程实现ActiveX控件调用cryptoAPI接口(二)------------信封加密与解密

注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.
[cpp]  view plain  copy
 print ?
  1. /* 
  2.  *  
  3.  *  
  4.  * 文件名称:Envelop.cpp 
  5.  * 摘    要: 
  6.  *      数字信封加密与解密 
  7.  * 当前版本:1.0 
  8.  * 作    者:周绍禹 
  9.  * 创建日期:2012年3月4日 
  10.  */  
  11. #include "StdAfx.h"  
  12. #include "Envelop.h"  
  13. #include "base64.h"  
  14. #include "Map.h"  
  15. #include <sstream>  
  16. #include "generic.h"  
  17.   
  18. Envelop::Envelop():CSP_NAME(FEITIAN_CSP_NAME)  
  19. {  
  20.     log = new Log("Envelop");  
  21.     certMsg = new CertMsg();  
  22. }  
  23.   
  24.   
  25. Envelop::~Envelop()  
  26. {  
  27.     delete log;  
  28.     delete certMsg;  
  29. }  
  30. //-----------------------------------------------------------  
  31. // 函数名称:  
  32. //     envelop  
  33. // 参数:  
  34. //    - string recCert_base64   用作非对称加密的公钥所对应的证书base64码  
  35. //    - string cipher_key_base64    信封加密的目标base64(在项目中也就是对称密钥)  
  36. // 返回:  
  37. //     Result*  
  38. // 说明:  
  39. //     会将目标base64码解码,后对得到的二进制数组进行信封加密  
  40. //     成功返回的为包含加密完成的信封base64码,或者返回异常信息  
  41. //-----------------------------------------------------------  
  42. Result* Envelop::envelop(string recCert_base64, string cipher_key_base64)  
  43. {  
  44.     // 公钥加密    
  45.   
  46.     //获取证书    
  47.     BYTE* rec_cert;    
  48.     int length;  
  49.     rec_cert = Base64::base64_decode(recCert_base64,length);    
  50.     int cipher_size;  
  51.     BYTE* msgContent = Base64::base64_decode(cipher_key_base64,cipher_size);  
  52.   
  53.   
  54.     PCCERT_CONTEXT  pRecverCert = NULL;               
  55.     if(!(pRecverCert = CertCreateCertificateContext(    
  56.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,               
  57.         rec_cert,     
  58.         length)))  
  59.     {    
  60.         string errorcode = getErrorCode();  
  61.         Result* result = new Result("Envelop.cpp",42,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);  
  62.         log->error("Envelop.cpp 45 CertCreateCertificateContext")->error(errorcode);   
  63.         if(rec_cert) delete[] rec_cert;  
  64.         if(msgContent) delete[] msgContent;  
  65.         return result;  
  66.     }    
  67.   
  68.     // 设置加密证书    
  69.     PCERT_INFO RecipCertArray[1];    
  70.     RecipCertArray[0] = pRecverCert->pCertInfo;    
  71.   
  72.     // 设置加密算法    
  73.     CRYPT_ALGORITHM_IDENTIFIER ContentEncryptAlgorithm;    
  74.     memset(&ContentEncryptAlgorithm, 0, sizeof(ContentEncryptAlgorithm));    
  75.     ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC2CBC;    
  76.   
  77.     // 设置信封参数    
  78.     CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;    
  79.     memset(&EnvelopedEncodeInfo, 0, sizeof(CMSG_ENVELOPED_ENCODE_INFO));    
  80.     EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);    
  81.     EnvelopedEncodeInfo.hCryptProv = NULL;    
  82.     EnvelopedEncodeInfo.ContentEncryptionAlgorithm = ContentEncryptAlgorithm;    
  83.     EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;    
  84.     EnvelopedEncodeInfo.cRecipients = 1;    
  85.     EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;    
  86.   
  87.     // 获取消息编码的长度    
  88.     CRYPT_DATA_BLOB encBlob;                 
  89.     memset(&encBlob, 0, sizeof(encBlob));    
  90.     encBlob.cbData = CryptMsgCalculateEncodedLength(    
  91.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,    
  92.         0,    
  93.         CMSG_ENVELOPED,    
  94.         &EnvelopedEncodeInfo,    
  95.         NULL,    
  96.         cipher_size);    
  97.     if(encBlob.cbData == 0)    
  98.     {    
  99.         CertFreeCertificateContext(pRecverCert);    
  100.         log->error("Envelop.cpp 85 CryptMsgCalculateEncodedLength")->error(getErrorCode());   
  101.         string errorcode = getErrorCode();  
  102.         Result* result = new Result("Envelop.cpp",79,"获取信封块大小失败!",errorcode.length()==0?"{}":errorcode);  
  103.   
  104.         if(rec_cert) delete[] rec_cert;  
  105.         if(msgContent) delete[] msgContent;  
  106.         if(pRecverCert) CertFreeCertificateContext(pRecverCert);   
  107.         return result;  
  108.     }    
  109.   
  110.   
  111.     // 分配编码空间    
  112.     encBlob.pbData = (BYTE *) new char[encBlob.cbData];    
  113.     if(encBlob.pbData == NULL)    
  114.     {    
  115.         string errorcode = getErrorCode();  
  116.         Result* result = new Result("Envelop.cpp",107,"分配编码空间失败!",errorcode.length()==0?"{}":errorcode);  
  117.         if(rec_cert) delete[] rec_cert;  
  118.         if(msgContent) delete[] msgContent;  
  119.         if(pRecverCert) CertFreeCertificateContext(pRecverCert);  
  120.         return result;  
  121.     }    
  122.     HCRYPTMSG hMsg;    
  123.     // 编码加密    
  124.     hMsg = CryptMsgOpenToEncode(    
  125.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,          
  126.         0,                         
  127.         CMSG_ENVELOPED,          
  128.         &EnvelopedEncodeInfo,    
  129.         NULL,                     
  130.         NULL);    
  131.     if(hMsg == NULL)     
  132.     {    
  133.         string errorcode = getErrorCode();  
  134.         log->error("Envelop.cpp 119 CryptMsgOpenToEncode")->error(errorcode);   
  135.         Result* result = new Result("Envelop.cpp",117,"获取信封块大小失败!",errorcode.length()==0?"{}":errorcode);  
  136.         if(rec_cert) delete[] rec_cert;  
  137.         if(msgContent) delete[] msgContent;  
  138.         if(pRecverCert) CertFreeCertificateContext(pRecverCert);  
  139.         return result;  
  140.     }    
  141.   
  142.     // 添加数据    
  143.     if(!CryptMsgUpdate(    
  144.         hMsg,                 
  145.         msgContent,         
  146.         cipher_size,          
  147.         TRUE))               
  148.     {    
  149.   
  150.         string errorcode = getErrorCode();  
  151.         log->error("Envelop.cpp 138 CryptMsgUpdate")->error(errorcode);   
  152.         Result* result = new Result("Envelop.cpp",141,"添加数据失败!",errorcode.length()==0?"{}":errorcode);  
  153.         if(rec_cert) delete[] rec_cert;  
  154.         if(msgContent) delete[] msgContent;  
  155.         if(pRecverCert) CertFreeCertificateContext(pRecverCert);  
  156.         if(hMsg) CryptMsgClose(hMsg);  
  157.         return result;  
  158.     }    
  159.   
  160.     // 获取加密结果    
  161.     if(!CryptMsgGetParam(    
  162.         hMsg,                          
  163.         CMSG_CONTENT_PARAM,             
  164.         0,                             
  165.         encBlob.pbData,                
  166.         &encBlob.cbData))            
  167.     {     
  168.         string errorcode = getErrorCode();  
  169.         log->error("Envelop.cpp 156 CryptMsgGetParam")->error(errorcode);   
  170.         Result* result = new Result("Envelop.cpp",157,"获得加密失败!",errorcode.length()==0?"{}":errorcode);  
  171.         if(rec_cert) delete[] rec_cert;  
  172.         if(msgContent) delete[] msgContent;  
  173.         if(pRecverCert) CertFreeCertificateContext(pRecverCert);  
  174.         if(hMsg) CryptMsgClose(hMsg);  
  175.         return result;  
  176.     }    
  177.   
  178.     string baseEnc = Base64::base64_encode(encBlob.pbData,encBlob.cbData);    
  179.   
  180.   
  181.     // 清理    
  182.     if(rec_cert) delete[] rec_cert;  
  183.     if(msgContent) delete[] msgContent;  
  184.   
  185.     if(encBlob.pbData) delete [] encBlob.pbData;    
  186.   
  187.     if(hMsg != NULL)    
  188.         CryptMsgClose(hMsg);    
  189.   
  190.     if(pRecverCert != NULL)    
  191.         CertFreeCertificateContext(pRecverCert);    
  192.   
  193.     Result* result = new Result(baseEnc);  
  194.     return result;    
  195. }  
  196. //-----------------------------------------------------------  
  197. // 函数名称:  
  198. //     develop  
  199. // 参数:  
  200. //    - string env_base64   加密的信封base64码  
  201. //    - BYTE* target_SN_blob    用来解密的数字证书序列号字节数组  
  202. //    - int cblob   用来解密的数字证书序列号字节数组大小  
  203. // 返回:  
  204. //     Result*  
  205. // 说明:  
  206. //     通过序列号查找到用来解密的证书,并获取私钥用作解密信封  
  207. //     成功返回的为包含目标的base64码(即对称密钥的Base64码),或者异常信息  
  208. //-----------------------------------------------------------  
  209. Result* Envelop::develop(string enc_base64,BYTE* target_SN_blob,int cblob)  
  210. {  
  211.     int encLen;   
  212.     BYTE* encBYTE;   
  213.     encBYTE = Base64::base64_decode(enc_base64,encLen);    
  214.   
  215.     HCRYPTPROV hProv;    
  216.   
  217.   
  218.     if(!CryptAcquireContext(&hProv,  
  219.         NULL,  
  220.         CSP_NAME,  
  221.         PROV_RSA_FULL,  
  222.         CRYPT_VERIFYCONTEXT))  
  223.     {  
  224.         DWORD dwLastErr = GetLastError();  
  225.         if(encBYTE) delete[] encBYTE;  
  226.         if(NTE_BAD_KEYSET == dwLastErr)   
  227.         {  
  228.             Result* result = new Result("Envelop.cpp",202,"密钥库不存在,或者访问被拒绝!","{}");  
  229.             return result;  
  230.         }  
  231.         else{  
  232.             if(!CryptAcquireContext(&hProv,  
  233.                 NULL,  
  234.                 this->CSP_NAME,  
  235.                 PROV_RSA_FULL,  
  236.                 CRYPT_NEWKEYSET))  
  237.             {  
  238.                 Map* map = new Map(1);  
  239.                 map->put("errcode",dwLastErr);  
  240.                 string errcode = map->toString();  
  241.                 delete map;  
  242.                 Result* result = new Result("Envelop.cpp",216,"密钥库已存在,创建密钥库失败!",errcode);  
  243.                 return result;  
  244.             }  
  245.         }  
  246.     }  
  247.   
  248.     HCRYPTMSG hMsg = NULL;     
  249.     hMsg = CryptMsgOpenToDecode(     
  250.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,      
  251.         0,                      
  252.         0,                     
  253.         NULL,                 
  254.         NULL,                 
  255.         NULL);                 
  256.     if(hMsg == NULL)     
  257.     {     
  258.         string errorcode = getErrorCode();  
  259.         log->error("Envelop.cpp 239 CryptMsgOpenToDecode")->error(errorcode);   
  260.         Result* result = new Result("Envelop.cpp",239,"获取解码句柄失败!",errorcode.length()==0?"{}":errorcode);  
  261.         if(encBYTE) delete[] encBYTE;  
  262.         if(hProv) CryptReleaseContext(hProv, 0);  
  263.         return result;  
  264.     }     
  265.   
  266.   
  267.     if(!CryptMsgUpdate(     
  268.         hMsg,                 
  269.         encBYTE,          
  270.         encLen + 1,          
  271.         TRUE))    
  272.     {    
  273.         string errorcode = getErrorCode();  
  274.         Result* result = new Result("Envelop.cpp",247,"解码失败!",errorcode.length()==0?"{}":errorcode);  
  275.         log->error("Envelop.cpp 257 CryptMsgUpdate")->error(errorcode);   
  276.         if(encBYTE) delete[] encBYTE;  
  277.         if(hProv) CryptReleaseContext(hProv, 0);  
  278.         if(hMsg) CryptMsgClose(hMsg);  
  279.         return result;  
  280.     }    
  281.   
  282.   
  283.     // 消息类型    
  284.     DWORD dwType = 0;     
  285.     DWORD dwSize = sizeof(dwType);    
  286.     if(!CryptMsgGetParam(     
  287.         hMsg,                    
  288.         CMSG_TYPE_PARAM,      
  289.         0,                      
  290.         &dwType,               
  291.         &dwSize))                
  292.     {     
  293.         CryptMsgClose(hMsg);    
  294.         string errorcode = getErrorCode();  
  295.         Result* result = new Result("Envelop.cpp",263,"解码失败!",errorcode.length()==0?"{}":errorcode);  
  296.         log->error("Envelop.cpp 276 CryptMsgGetParam")->error(errorcode);   
  297.         if(encBYTE) delete[] encBYTE;  
  298.         if(hProv) CryptReleaseContext(hProv, 0);  
  299.         if(hMsg) CryptMsgClose(hMsg);  
  300.         return result;     
  301.     }    
  302.   
  303.     // 校验消息类型    
  304.     if (dwType != CMSG_ENVELOPED)     
  305.     {     
  306.         Result* result = new Result("Envelop.cpp",274,"消息类型错误!","{}");  
  307.         if(encBYTE) delete[] encBYTE;  
  308.         if(hProv) CryptReleaseContext(hProv, 0);  
  309.         if(hMsg) CryptMsgClose(hMsg);  
  310.         return result;  
  311.     }     
  312.   
  313.     // 消息格式    
  314.     char szTypeName[1024];    
  315.     dwSize = 1024;    
  316.     if(!CryptMsgGetParam(     
  317.         hMsg,                              
  318.         CMSG_INNER_CONTENT_TYPE_PARAM,      
  319.         0,                                  
  320.         szTypeName,                         
  321.         &dwSize))                         
  322.     {    
  323.         string errorcode = getErrorCode();  
  324.         Result* result = new Result("Envelop.cpp",287,"获取消息格式失败!",errorcode.length()==0?"{}":errorcode);  
  325.         log->error("Envelop.cpp 306 CryptMsgGetParam")->error(errorcode);   
  326.         if(encBYTE) delete[] encBYTE;  
  327.         if(hProv) CryptReleaseContext(hProv, 0);  
  328.         if(hMsg) CryptMsgClose(hMsg);  
  329.         return result;    
  330.     }    
  331.   
  332.     // 检查消息格式    
  333.     if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0)     
  334.     {    
  335.         Result* result = new Result("Envelop.cpp",287,"消息格式错误!","{}");  
  336.         if(encBYTE) delete[] encBYTE;  
  337.         if(hProv) CryptReleaseContext(hProv, 0);  
  338.         if(hMsg) CryptMsgClose(hMsg);  
  339.         return result;     
  340.     }     
  341.   
  342.     // 请求证书私钥服务    
  343.     HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;    
  344.     DWORD dwKeyType = 0;    
  345.     BOOL bFreeKeyProv = FALSE;    
  346.   
  347.   
  348.     Result* result_privateKey = certMsg->acquirePrivateKey(hProv,target_SN_blob,cblob,&hKeyProv,&dwKeyType);  
  349.   
  350.     if(!result_privateKey->isSuccess())  
  351.     {  
  352.         log->error("Envelop.cpp 338 acquirePrivateKey");   
  353.         if(encBYTE) delete[] encBYTE;  
  354.         if(hProv) CryptReleaseContext(hProv, 0);  
  355.         if(hMsg) CryptMsgClose(hMsg);  
  356.         if(hKeyProv) CryptReleaseContext(hKeyProv, 0);  
  357.         return result_privateKey;  
  358.     }  
  359.   
  360.     if(hKeyProv==NULL)  
  361.     {  
  362.         string errorcode = getErrorCode();  
  363.         Result* result = new Result("Envelop.cpp",316,"获取私钥服务失败!",errorcode.length()==0?"{}":errorcode);  
  364.         if(encBYTE) delete[] encBYTE;  
  365.         if(hProv) CryptReleaseContext(hProv, 0);  
  366.         if(hMsg) CryptMsgClose(hMsg);  
  367.         return result;    
  368.     }  
  369.   
  370.     CMSG_CTRL_DECRYPT_PARA para;     
  371.     para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA);     
  372.     para.dwKeySpec = dwKeyType;     
  373.     para.hCryptProv = hKeyProv;     
  374.     para.dwRecipientIndex = 0;   
  375.     if(!CryptMsgControl(     
  376.         hMsg,                 
  377.         0,                     
  378.         CMSG_CTRL_DECRYPT,      
  379.         ¶))                  
  380.     {    
  381.         string errorcode = getErrorCode();  
  382.         Result* result = new Result("Envelop.cpp",335,"解密控制失败!",errorcode.length()==0?"{}":errorcode);  
  383.         log->error("Envelop.cpp 364 CryptMsgControl")->error(errorcode);   
  384.         if(encBYTE) delete[] encBYTE;  
  385.         if(hProv) CryptReleaseContext(hProv, 0);  
  386.         if(hMsg) CryptMsgClose(hMsg);  
  387.         if(hKeyProv) CryptReleaseContext(hKeyProv, 0);  
  388.         return result;     
  389.     }    
  390.   
  391.     // 获取解密消息大小    
  392.     CRYPT_DATA_BLOB sigBlob;    
  393.     memset(&sigBlob, 0, sizeof(sigBlob));    
  394.     if(!CryptMsgGetParam(     
  395.         hMsg,                  
  396.         CMSG_CONTENT_PARAM,   
  397.         0,                      
  398.         NULL,                  
  399.         &sigBlob.cbData))      
  400.     {                        
  401.         string errorcode = getErrorCode();  
  402.         Result* result = new Result("Envelop.cpp",351,"获取解密消息大小失败!",errorcode.length()==0?"{}":errorcode);  
  403.         log->error("Envelop.cpp 382 CryptMsgGetParam")->error(errorcode);   
  404.         if(encBYTE) delete[] encBYTE;  
  405.         if(hProv) CryptReleaseContext(hProv, 0);  
  406.         if(hMsg) CryptMsgClose(hMsg);  
  407.         if(hKeyProv) CryptReleaseContext(hKeyProv, 0);  
  408.         return result;     
  409.     }     
  410.   
  411.     // 分配内存    
  412.     sigBlob.pbData =  new BYTE[sigBlob.cbData];    
  413.     if(sigBlob.pbData == NULL)    
  414.     {    
  415.         string errorcode = getErrorCode();  
  416.         Result* result = new Result("Envelop.cpp",366,"分配内存空间失败!",errorcode.length()==0?"{}":errorcode);  
  417.         if(encBYTE) delete[] encBYTE;  
  418.         if(hProv) CryptReleaseContext(hProv, 0);  
  419.         if(hMsg) CryptMsgClose(hMsg);  
  420.         if(hKeyProv) CryptReleaseContext(hKeyProv, 0);  
  421.         return result;     
  422.     }    
  423.   
  424.     // 获取解码消息    
  425.     if(!CryptMsgGetParam(     
  426.         hMsg,                  
  427.         CMSG_CONTENT_PARAM,   
  428.         0,                      
  429.         sigBlob.pbData,          
  430.         &sigBlob.cbData))     
  431.     {                        
  432.         string errorcode = getErrorCode();  
  433.         Result* result = new Result("Envelop.cpp",377,"获取解码消息失败!",errorcode.length()==0?"{}":errorcode);  
  434.         log->error("Envelop.cpp 411 CryptMsgGetParam")->error(errorcode);   
  435.         if(encBYTE) delete[] encBYTE;  
  436.         if(hProv) CryptReleaseContext(hProv, 0);  
  437.         if(hMsg) CryptMsgClose(hMsg);  
  438.         if(hKeyProv) CryptReleaseContext(hKeyProv, 0);  
  439.         return result;     
  440.     }    
  441.     sigBlob.pbData[sigBlob.cbData]='\0';    
  442.     // 清理解密过程数据    
  443.     if(encBYTE) delete[] encBYTE;  
  444.     if(hProv) CryptReleaseContext(hProv, 0);  
  445.     if(hMsg) CryptMsgClose(hMsg);  
  446.     if(hKeyProv) CryptReleaseContext(hKeyProv, 0);  
  447.     string text = Base64::base64_encode(sigBlob.pbData,sigBlob.cbData);  
  448.   
  449.     Result* result = new Result(text);  
  450.     return result;    
  451. }  



------------------------------下面为刚接触的版本,上面为修改后的版本--------------------------


代码有待修改

信封加密与解密


[cpp]  view plain  copy
 print ?
  1. #include "Base.h"  //Base64转码  
  2. #include <comdef.h>  
  3. #include <stdio.h>  
  4. #include <conio.h>  
  5. #include <windows.h>  
  6. #include <wincrypt.h>  
  7. #include <iostream>  
  8. using namespace std;  
  9. #define TEST_CSP_NAME    "FEITIAN ePassNG RSA Cryptographic Service Provider" //飞天CSP  
  10. //加密信封  
  11. STDMETHODIMP CEnvelop::Envelop(BSTR recCert_base64_bstr, BSTR plainText_bstr, BSTR* envelopedData)  
  12. {  
  13.     string recCert_base64 = _bstr_t(recCert_base64_bstr);  
  14.     string plainText = _bstr_t(plainText_bstr);  
  15.     // TODO: Add your implementation code here  
  16.     // 公钥加密  
  17.   
  18.     //获取证书  
  19.     BYTE* rec_cert;  
  20.     string rec_cstrCert_base64 = recCert_base64;  
  21.     string rec_decodeCert = base64_decode(rec_cstrCert_base64);  
  22.     int rec_certLen = rec_decodeCert.size();  
  23.     rec_cert = new BYTE[rec_certLen] ;  
  24.     for(int i = 0; i < rec_certLen; ++i)  
  25.     {  
  26.         rec_cert[i] = (byte)rec_decodeCert[i];  
  27.     }  
  28.     rec_cert[rec_certLen] = '\0';  
  29.     PCCERT_CONTEXT  pRecverCert = NULL;  
  30.     if(pRecverCert = CertCreateCertificateContext(  
  31.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,              // The encoding type  
  32.         rec_cert,   // The encoded data from  
  33.         // the certificate retrieved  
  34.         rec_certLen))  // The length of the encoded data  
  35.     {  
  36.         printf("A new certificate has been created.\n");  
  37.   
  38.         // Use the certificate context as needed.  
  39.         // ...  
  40.     }  
  41.     else  
  42.     {  
  43.         printf("A new certificate could not be created.\n");  
  44.     }  
  45.   
  46.     // 设置加密证书  
  47.     PCERT_INFO RecipCertArray[1];  
  48.     RecipCertArray[0] = pRecverCert->pCertInfo;  
  49.   
  50.     // 设置加密算法  
  51.     CRYPT_ALGORITHM_IDENTIFIER ContentEncryptAlgorithm;  
  52.     memset(&ContentEncryptAlgorithm, 0, sizeof(ContentEncryptAlgorithm));  
  53.     ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC2CBC;  
  54.   
  55.     // 设置信封参数  
  56.     CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;  
  57.     memset(&EnvelopedEncodeInfo, 0, sizeof(CMSG_ENVELOPED_ENCODE_INFO));  
  58.     EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);  
  59.     EnvelopedEncodeInfo.hCryptProv = NULL;  
  60.     EnvelopedEncodeInfo.ContentEncryptionAlgorithm = ContentEncryptAlgorithm;  
  61.     EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;  
  62.     EnvelopedEncodeInfo.cRecipients = 1;  
  63.     EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;  
  64.   
  65.     // 获取消息编码的长度  
  66.     CRYPT_DATA_BLOB encBlob;  
  67.     memset(&encBlob, 0, sizeof(encBlob));  
  68.     encBlob.cbData = CryptMsgCalculateEncodedLength(  
  69.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,  
  70.         0,  
  71.         CMSG_ENVELOPED,  
  72.         &EnvelopedEncodeInfo,  
  73.         NULL,  
  74.         plainText.size());  
  75.     if(encBlob.cbData == 0)  
  76.     {  
  77.         CertFreeCertificateContext(pRecverCert);  
  78.         printf("Getting enveloped cbEncodedBlob length failed.");  
  79.     }  
  80.   
  81.     printf("Enveloped message size is %d bytes.", encBlob.cbData);  
  82.   
  83.     // 分配编码空间  
  84.     encBlob.pbData = (BYTE *) new char[encBlob.cbData];  
  85.     if(encBlob.pbData == NULL)  
  86.     {  
  87.         CertFreeCertificateContext(pRecverCert);  
  88.         printf("Memory allocation failed. \n");  
  89.     }  
  90.     HCRYPTMSG hMsg;  
  91.     // 编码加密  
  92.     hMsg = CryptMsgOpenToEncode(  
  93.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,        // encoding type  
  94.         0,                       // flags  
  95.         CMSG_ENVELOPED,          // message type  
  96.         &EnvelopedEncodeInfo,    // pointer to structure  
  97.         NULL,                     // szOID_RSA_signedData,    // inner content OID  
  98.         NULL);  
  99.     if(hMsg == NULL)   
  100.     {  
  101.         delete [] encBlob.pbData;  
  102.         CertFreeCertificateContext(pRecverCert);  
  103.         printf("The message open to be encode failed. \n");  
  104.     }  
  105.     BYTE* msgContent;  
  106.     int size = plainText.size();  
  107.     msgContent = new BYTE[size];  
  108.     for(int i=0;i<size;i++){  
  109.         msgContent[i]=(BYTE)plainText[i];  
  110.     }  
  111.     msgContent[size]='\0';  
  112.     // 添加数据  
  113.     if(!CryptMsgUpdate(  
  114.         hMsg,                // handle to the message  
  115.         msgContent,        // pointer to the content  
  116.         size,        // size of the content  
  117.         TRUE))                // last call  
  118.     {  
  119.         delete [] encBlob.pbData;  
  120.         CryptMsgClose(hMsg);  
  121.         CertFreeCertificateContext(pRecverCert);  
  122.         printf("Enveloped CryptMsgUpdate failed.\n");  
  123.     }  
  124.   
  125.     // 获取加密结果  
  126.     if(!CryptMsgGetParam(  
  127.         hMsg,                        // handle to the message  
  128.         CMSG_CONTENT_PARAM,            // parameter type  
  129.         0,                            // index  
  130.         encBlob.pbData,                // pointer to the BLOB  
  131.         &encBlob.cbData))            // size of the BLOB  
  132.     {  
  133.         delete [] encBlob.pbData;  
  134.         CryptMsgClose(hMsg);  
  135.         CertFreeCertificateContext(pRecverCert);  
  136.         printf("CryptMsgGetParam enveloped message failed.\n");  
  137.     }  
  138.   
  139.     string baseEnc = base64_encode(encBlob.pbData,encBlob.cbData);  
  140.     // 清理  
  141.     delete [] encBlob.pbData;  
  142.   
  143.     if(hMsg != NULL)  
  144.     {  
  145.         CryptMsgClose(hMsg);  
  146.         hMsg = NULL;  
  147.     }  
  148.   
  149.     if(pRecverCert != NULL)  
  150.     {  
  151.         CertFreeCertificateContext(pRecverCert);  
  152.         pRecverCert = NULL;  
  153.     }  
  154.   
  155.     CComBSTR bstr(baseEnc.c_str());  
  156.     *envelopedData = bstr;  
  157.     return S_OK;  
  158. }  
  159.   
  160. //解密信封  
  161. STDMETHODIMP CEnvelop::Develop(BSTR enc_base64_bstr, BSTR* plainText)  
  162. {  
  163.     string enc_base64 = _bstr_t(enc_base64_bstr);  
  164.     // TODO: Add your implementation code here  
  165.     string enc = base64_decode(enc_base64);  
  166.     int encLen = enc.size();  
  167.     BYTE* encBYTE;  
  168.     encBYTE = new BYTE[encLen];  
  169.   
  170.     for(int i=0;i<encLen;i++){  
  171.         encBYTE[i]=enc[i];  
  172.     }  
  173.     encBYTE[encLen]='\0';  
  174.       
  175.     // 准备数据  
  176.     HCRYPTPROV hProv;  
  177.     //  --------------------------------------------------------------------  
  178.     // get the CSP handle  
  179.     printf("The following phase of this program is signature.\n\n");  
  180.     if(CryptAcquireContext(  
  181.         &hProv,   
  182.         NULL,   
  183.         TEST_CSP_NAME,  
  184.         PROV_RSA_FULL,   
  185.         0))   
  186.     {  
  187.         printf("CSP context acquired.\n");  
  188.     }  
  189.     else    //create if not exist  
  190.     {  
  191.         if(CryptAcquireContext(  
  192.             &hProv,   
  193.             NULL,   
  194.             TEST_CSP_NAME,   
  195.             PROV_RSA_FULL,   
  196.             CRYPT_NEWKEYSET))   
  197.         {  
  198.             printf("A new key container has been created.\n");  
  199.         }  
  200.         else  
  201.         {  
  202.         }  
  203.     }  
  204.     // Open  
  205.     HCRYPTMSG hMsg = NULL;   
  206.     hMsg = CryptMsgOpenToDecode(   
  207.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,    // Encoding type.   
  208.         0,                    // Flags.   
  209.         0,                    // Use the default message type which is listed in the message header.   
  210.         NULL,                // Cryptographic provider. Use NULL for the default provider.   
  211.         NULL,                // Recipient information.   
  212.         NULL);                // Stream information.   
  213.     if(hMsg == NULL)   
  214.     {   
  215.         printf("Failed in CryptMsgOpenToDecode.");   
  216.     }   
  217.   
  218.     // Update  
  219.     if(!CryptMsgUpdate(   
  220.         hMsg,                // Handle to the message   
  221.         encBYTE,        // Pointer to the encoded BLOB   
  222.         encLen,        // Size of the encoded BLOB   
  223.         TRUE))  
  224.     {  
  225.         CryptMsgClose(hMsg);  
  226.         printf("Failed in CryptMsgUpdate.");   
  227.     }  
  228.   
  229.   
  230.     // 开始操作解码后的加密数据 ================================  
  231.   
  232.     // 消息类型  
  233.     DWORD dwType = 0;   
  234.     DWORD dwSize = sizeof(dwType);  
  235.     if(!CryptMsgGetParam(   
  236.         hMsg,                // Handle to the message   
  237.         CMSG_TYPE_PARAM,    // Parameter type   
  238.         0,                    // Index   
  239.         &dwType,            // Buffer  
  240.         &dwSize))            // Size of the returned   
  241.     {   
  242.         CryptMsgClose(hMsg);  
  243.         printf("Failed in CryptMsgGetParam for CMSG_TYPE_PARAM.");   
  244.     }  
  245.   
  246.     // 校验消息类型  
  247.     if (dwType != CMSG_ENVELOPED)   
  248.     {   
  249.         CryptMsgClose(hMsg);  
  250.         printf("Not an enveloped data.");   
  251.     }   
  252.   
  253.     // 消息格式  
  254.     char szTypeName[1024];  
  255.     dwSize = 1024;  
  256.     if(!CryptMsgGetParam(   
  257.         hMsg,                            // Handle to the message   
  258.         CMSG_INNER_CONTENT_TYPE_PARAM,    // Parameter type   
  259.         0,                                // Index   
  260.         szTypeName,                        // Buffer   
  261.         &dwSize))                        // Size of the returned   
  262.     {  
  263.         CryptMsgClose(hMsg);  
  264.         printf("Failed in CryptMsgGetParam for CMSG_INNER_CONTENT_TYPE_PARAM.");   
  265.     }  
  266.   
  267.     // 检查消息格式  
  268.     if(strcmp(szTypeName, szOID_PKCS_7_DATA) != 0)   
  269.     {  
  270.         //        CryptMsgClose(hMsg);  
  271.         //      printf("The inner content is not szOID_PKCS_7_DATA.");   
  272.     }   
  273.   
  274.     // 打开证书库  
  275.     HCERTSTORE hCertStore = CertOpenStore(  
  276.         CERT_STORE_PROV_SYSTEM,   // The store provider type.  
  277.         0,                        // The encoding type is not needed.  
  278.         hProv,               // Use the epassNG HCRYPTPROV.  
  279.         CERT_SYSTEM_STORE_CURRENT_USER,  
  280.         L"MY"  
  281.         );  
  282.     if(hCertStore == NULL)  
  283.     {  
  284.   
  285.     }  
  286.   
  287.     // 查找证书  
  288.     PCCERT_CONTEXT hCert = CertFindCertificateInStore(  
  289.         hCertStore,  
  290.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,  
  291.         0,  
  292.         CERT_FIND_SUBJECT_STR,  
  293.         L"周绍禹",  
  294.         NULL);  
  295.     if(hCert == NULL)  
  296.     {  
  297.   
  298.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  299.     }  
  300.   
  301.   
  302.     /**//* 
  303.         BOOL WINAPI CryptAcquireCertificatePrivateKey( 
  304.         __in          PCCERT_CONTEXT pCert, 
  305.         __in          DWORD dwFlags, 
  306.         __in          void* pvReserved, 
  307.         __out         HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey, 
  308.         __out         DWORD* pdwKeySpec, 
  309.         __out         BOOL* pfCallerFreeProvOrNCryptKey 
  310.         ); 
  311.         */  
  312.     // 请求证书私钥服务  
  313.     HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;  
  314.     DWORD dwKeyType = 0;  
  315.     BOOL bFreeKeyProv = FALSE;  
  316.     if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))  
  317.     {  
  318.   
  319.         CertFreeCertificateContext(hCert);  
  320.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  321.     }  
  322.   
  323.       
  324.     CMSG_CTRL_DECRYPT_PARA para;   
  325.     para.cbSize = sizeof (CMSG_CTRL_DECRYPT_PARA);   
  326.     para.dwKeySpec = dwKeyType;   
  327.     para.hCryptProv = hProv;   
  328.     para.dwRecipientIndex = 0;   
  329.     if(!CryptMsgControl(   
  330.         hMsg,                // Handle to the message   
  331.         0,                    // Flags   
  332.         CMSG_CTRL_DECRYPT,    // Control type   
  333.         ¶))                // Pointer to the CERT_INFO   
  334.     {  
  335.         CryptMsgClose(hMsg);  
  336.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  337.         printf("Failed in CryptMsgControl.");   
  338.     }  
  339.   
  340.     // 获取解密消息大小  
  341.     CRYPT_DATA_BLOB sigBlob;  
  342.     memset(&sigBlob, 0, sizeof(sigBlob));  
  343.     if(!CryptMsgGetParam(   
  344.         hMsg,                // Handle to the message   
  345.         CMSG_CONTENT_PARAM, // Parameter type   
  346.         0,                    // Index   
  347.         NULL,                //  
  348.         &sigBlob.cbData))    // Size of the returned   
  349.     {                      
  350.         CryptMsgClose(hMsg);  
  351.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  352.         printf("Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");   
  353.     }   
  354.   
  355.     // 分配内存  
  356.     sigBlob.pbData = (BYTE *) new char[sigBlob.cbData];  
  357.     if(sigBlob.pbData == NULL)  
  358.     {  
  359.         CryptMsgClose(hMsg);  
  360.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  361.         printf("Not enough memory.");   
  362.     }  
  363.   
  364.     // 获取解码消息  
  365.     if(!CryptMsgGetParam(   
  366.         hMsg,                // Handle to the message   
  367.         CMSG_CONTENT_PARAM, // Parameter type   
  368.         0,                    // Index   
  369.         sigBlob.pbData,        //  
  370.         &sigBlob.cbData))    // Size of the returned   
  371.     {                      
  372.         delete [] sigBlob.pbData;  
  373.         CryptMsgClose(hMsg);  
  374.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  375.         printf("Failed in CryptMsgGetParam for CMSG_CONTENT_PARAM.");   
  376.     }  
  377.     sigBlob.pbData[sigBlob.cbData]='\0';  
  378.     // 清理解密过程数据  
  379.     CryptMsgClose(hMsg);  
  380.     CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  381.   
  382.     printf("Enveloped message decrypt successfully. \n");   
  383.     char* text = (char*)sigBlob.pbData;  
  384.     CComBSTR bstr(text);  
  385.     *plainText = bstr;  
  386.     return S_OK;  
  387. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值