编写ATL工程实现ActiveX控件调用cryptoAPI接口(一)------------签名与验证

注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.
[cpp]  view plain  copy
 print ?
  1. /* 
  2.  
  3.  
  4. * 文件名称:Signer.cpp 
  5. * 摘    要: 
  6. *       数字签名及验证 
  7. * 当前版本:1.0 
  8. * 作    者:周绍禹 
  9. * 创建日期:2012年3月4日 
  10. */  
  11. #include "StdAfx.h"  
  12. #include "Signer.h"  
  13. #include "Map.h"  
  14. #include "generic.h"  
  15. #include "base64.h"  
  16. Signer::Signer():CSP_NAME(FEITIAN_CSP_NAME)  
  17. {  
  18.     log = new Log("Signer");  
  19.     certMsg = new CertMsg();  
  20. }  
  21.   
  22.   
  23. Signer::~Signer()  
  24. {  
  25.     if(log) delete log;  
  26.     if(certMsg) delete certMsg;  
  27. }  
  28. //-----------------------------------------------------------  
  29. // 函数名称:  
  30. //     sign  
  31. // 参数:  
  32. //    - string plain_text   明文  
  33. //    - BYTE* target_SN_blob    目标证书的序列号字节数组  
  34. //    - int cblob   目标证书的序列号字节数组大小  
  35. // 返回:  
  36. //     Result*  
  37. // 说明:  
  38. //     通过指定的序列号查找证书以及私钥,对数据做数字签名操作  
  39. //-----------------------------------------------------------  
  40. Result* Signer::sign(string plain_text,BYTE* target_SN_blob,int cblob)  
  41. {  
  42.     // 准备数据    
  43.     HCRYPTPROV hProv;    
  44.     if(!CryptAcquireContext(&hProv,  
  45.         NULL,  
  46.         CSP_NAME,  
  47.         PROV_RSA_FULL,  
  48.         CRYPT_VERIFYCONTEXT))  
  49.     {  
  50.         DWORD dwLastErr = GetLastError();  
  51.   
  52.   
  53.         if(NTE_BAD_KEYSET == dwLastErr)   
  54.         {  
  55.             Result* result = new Result("Signer.cpp",20,"密钥库不存在,或者访问被拒绝!","{}");  
  56.             return result;  
  57.         }  
  58.         else{  
  59.             if(!CryptAcquireContext(&hProv,  
  60.                 NULL,  
  61.                 this->CSP_NAME,  
  62.                 PROV_RSA_FULL,  
  63.                 CRYPT_NEWKEYSET))  
  64.             {  
  65.                 Map* map = new Map(1);  
  66.                 map->put("errcode",dwLastErr);  
  67.                 string errcode = map->toString();  
  68.                 delete map;  
  69.                 Result* result = new Result("Signer.cpp",34,"密钥库已存在,创建密钥库失败!",errcode);  
  70.                 return result;  
  71.             }  
  72.         }  
  73.     }  
  74.   
  75.     // 请求证书私钥服务    
  76.     HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;    
  77.     DWORD dwKeyType = 0;    
  78.   
  79.   
  80.     Result* result = certMsg->acquirePrivateKey(hProv,target_SN_blob,cblob,&hKeyProv,&dwKeyType);  
  81.   
  82.     if(!result->isSuccess())  
  83.     {  
  84.         if(hProv != NULL)    
  85.             CryptReleaseContext(hProv, 0);  
  86.         log->error("Signer.cpp 86 acquirePrivateKey")->error(getErrorCode());  
  87.         return result;  
  88.     }  
  89.   
  90.     if(hKeyProv==NULL)  
  91.     {  
  92.         string errorcode = getErrorCode();  
  93.         Result* result = new Result("Signer.cpp",57,"获取私钥服务失败!",errorcode.length()==0?"{}":errorcode);  
  94.         if(hProv != NULL)    
  95.             CryptReleaseContext(hProv, 0);  
  96.         log->error("Signer.cpp 86 acquirePrivateKey")->error(errorcode);  
  97.         return result;    
  98.     }  
  99.   
  100.     // 创建离散对象    
  101.     HCRYPTHASH hHash = NULL;    
  102.     if(!CryptCreateHash(    
  103.         hKeyProv,                    // 容器句柄     
  104.         CALG_MD5,                    // 算法标识    
  105.         NULL,                        // 算法使用的Key    
  106.         0,                            // 算法标识    
  107.         &hHash))                    // 返回的HASH对象    
  108.     {    
  109.         string errorcode = getErrorCode();  
  110.         Result* result = new Result("Singer.cpp",73,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);  
  111.         log->error("Signer.cpp 102 CryptCreateHash")->error(errorcode);  
  112.         if(hProv != NULL)    
  113.             CryptReleaseContext(hProv, 0);  
  114.         if(hKeyProv != NULL)    
  115.             CryptReleaseContext(hKeyProv, 0);  
  116.         return result;     
  117.     }    
  118.   
  119.   
  120.     BYTE *orgTextByte ;    
  121.     int orgTextLen = plain_text.size();    
  122.     orgTextByte = new BYTE[orgTextLen + 1];    
  123.     for(int i=0;i<orgTextLen;i++){    
  124.         orgTextByte[i]=plain_text[i];    
  125.     }    
  126.     orgTextByte[orgTextLen]='\0';    
  127.     // 计算数据摘要    
  128.     if(!CryptHashData(hHash, orgTextByte, orgTextLen, 0))    
  129.     {    
  130.         string errorcode = getErrorCode();  
  131.         Result* result = new Result("Signer.cpp",94,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);  
  132.   
  133.         log->error("Signer.cpp 128 CryptHashData")->error(errorcode);  
  134.         if(hProv != NULL)    
  135.             CryptReleaseContext(hProv, 0);  
  136.         if(hKeyProv != NULL)    
  137.             CryptReleaseContext(hKeyProv, 0);  
  138.         if(hHash)   
  139.             CryptDestroyHash(hHash);     
  140.         if(orgTextByte) delete[] orgTextByte;  
  141.         return result;   
  142.     }    
  143.   
  144.     DWORD cbSign = 4096;    
  145.     BYTE  *pbSign;    
  146.     //获取签名数据摘要大小    
  147.     if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))    
  148.     {    
  149.         string errorcode = getErrorCode();  
  150.         Result* result = new Result("Signer.cpp",106,"获取签名大小失败!",errorcode.length()==0?"{}":errorcode);  
  151.         log->error("Signer.cpp 147 CryptSignHash")->error(errorcode);  
  152.         if(hProv != NULL)    
  153.             CryptReleaseContext(hProv, 0);  
  154.         if(hKeyProv != NULL)    
  155.             CryptReleaseContext(hKeyProv, 0);  
  156.         if(hHash)   
  157.             CryptDestroyHash(hHash);     
  158.         if(orgTextByte) delete[] orgTextByte;  
  159.         return result;  
  160.     }    
  161.     pbSign = new BYTE[cbSign];    
  162.     //签名数据摘要    
  163.     if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))    
  164.     {    
  165.         string errorcode = getErrorCode();  
  166.         Result* result = new Result("Signer.cpp",116,"签名失败!",errorcode.length()==0?"{}":errorcode);  
  167.         log->error("Signer.cpp 163 CryptSignHash")->error(errorcode);  
  168.         if(hProv != NULL)    
  169.             CryptReleaseContext(hProv, 0);  
  170.         if(hKeyProv != NULL)    
  171.             CryptReleaseContext(hKeyProv, 0);  
  172.         if(hHash)   
  173.             CryptDestroyHash(hHash);     
  174.         if(orgTextByte) delete[] orgTextByte;  
  175.         if(pbSign) delete[] pbSign;  
  176.         return result;    
  177.     }    
  178.   
  179.     //将签名值转成base64编码    
  180.     string baseSign = Base64::base64_encode(pbSign,cbSign);    
  181.     log->info("----------------------")->info("签名值:")->info(baseSign);  
  182.   
  183.   
  184.     if(hProv != NULL)    
  185.         CryptReleaseContext(hProv, 0);  
  186.     if(hKeyProv != NULL)    
  187.         CryptReleaseContext(hKeyProv, 0);  
  188.     if(hHash)   
  189.         CryptDestroyHash(hHash);     
  190.     if(orgTextByte) delete[] orgTextByte;  
  191.     if(pbSign) delete[] pbSign;  
  192.   
  193.     Result* sign_result = new Result(baseSign);  
  194.   
  195.     return sign_result;    
  196. }  
  197. //-----------------------------------------------------------  
  198. // 函数名称:  
  199. //     verify  
  200. // 参数:  
  201. //    - string signed_text_base64   签名值base64码  
  202. //    - string cert_base64  数字证书base64码  
  203. //    - string org_text 明文  
  204. // 返回:  
  205. //     Result*  
  206. // 说明:  
  207. //     使用传入的证书base64码创建证书上下文,然后使用该证书及其公钥验证数字签名  
  208. //-----------------------------------------------------------  
  209. Result* Signer::verify(string signed_text_base64,string cert_base64,string org_text)  
  210. {  
  211.     BYTE* signedData;    
  212.     int length;  
  213.     signedData = Base64::base64_decode(signed_text_base64,length);     
  214.     // 请求容器服务    
  215.     HCRYPTPROV hProv = NULL;     
  216.     if(!CryptAcquireContext(&hProv,  
  217.         NULL,  
  218.         CSP_NAME,  
  219.         PROV_RSA_FULL,  
  220.         CRYPT_VERIFYCONTEXT))  
  221.     {  
  222.         DWORD dwLastErr = GetLastError();  
  223.         if(signedData) delete[] signedData;  
  224.         if(NTE_BAD_KEYSET == dwLastErr)   
  225.         {  
  226.             Result* result = new Result("Signer.cpp",164,"密钥库不存在,或者访问被拒绝!","{}");  
  227.             return result;  
  228.         }  
  229.         else{  
  230.             if(!CryptAcquireContext(&hProv,  
  231.                 NULL,  
  232.                 this->CSP_NAME,  
  233.                 PROV_RSA_FULL,  
  234.                 CRYPT_NEWKEYSET))  
  235.             {  
  236.                 Map* map = new Map(1);  
  237.                 map->put("errcode",dwLastErr);  
  238.                 string errcode = map->toString();  
  239.                 delete map;  
  240.                 Result* result = new Result("Signer.cpp",178,"密钥库已存在,创建密钥库失败!",errcode);  
  241.                 return result;  
  242.             }  
  243.         }  
  244.     }  
  245.   
  246.     // 创建离散对象    
  247.     HCRYPTHASH hHash = NULL;    
  248.     if(!CryptCreateHash(    
  249.         hProv,                        // 容器句柄     
  250.         CALG_MD5,                    // 算法标识    
  251.         NULL,                        // 算法使用的Key    
  252.         0,                            // 算法标识    
  253.         &hHash))                    // 返回的HASH对象    
  254.     {    
  255.         string errorcode = getErrorCode();  
  256.         Result* result = new Result("Singer.cpp",196,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);  
  257.         log->error("Signer.cpp 248 CryptCreateHash")->error(errorcode);  
  258.         if(signedData) delete[] signedData;  
  259.         if(hProv) CryptReleaseContext(hProv,0);  
  260.         return result;     
  261.     }    
  262.     BYTE* orgBlob;           
  263.     int orglen = org_text.size();    
  264.     orgBlob = new BYTE[orglen + 1] ;    
  265.     for(int i = 0; i < orglen; ++i)    
  266.     {    
  267.         orgBlob[i] = (byte)org_text[i];    
  268.     }    
  269.     orgBlob[orglen] = '\0';    
  270.     // 计算数据摘要    
  271.     if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)    
  272.     {    
  273.         string errorcode = getErrorCode();  
  274.         Result* result = new Result("Singer.cpp",216,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);  
  275.         log->error("Signer.cpp 271 CryptHashData")->error(errorcode);  
  276.         if(signedData) delete[] signedData;  
  277.         if(hProv) CryptReleaseContext(hProv,0);  
  278.         if(orgBlob) delete[] orgBlob;  
  279.         if(hHash) CryptDestroyHash(hHash);  
  280.         return result;  
  281.     }    
  282.   
  283.     // 获取签名者证书公钥    
  284.   
  285.     BYTE* cert;       
  286.     int len;  
  287.     cert = Base64::base64_decode(cert_base64,len);    
  288.     char* len_log_str = new char[20];  
  289.     itoa(len,len_log_str,10);  
  290.     log->info("-----------------------")->info("Signer.cpp 290 CertCreateCertificateContext")->info(cert_base64)->info(len_log_str);  
  291.     PCCERT_CONTEXT  pCertContext = NULL;    
  292.     pCertContext = CertCreateCertificateContext(    
  293.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,                
  294.         cert,     
  295.         len) ;  
  296.     if(pCertContext == NULL)    
  297.     {    
  298.         string errorcode = getErrorCode();  
  299.         Result* result = new Result("Singer.cpp",238,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);  
  300.         log->error("Signer.cpp 290 CertCreateCertificateContext")->error(errorcode);  
  301.         if(signedData) delete[] signedData;  
  302.         if(hProv) CryptReleaseContext(hProv,0);  
  303.         if(orgBlob) delete[] orgBlob;  
  304.         if(hHash) CryptDestroyHash(hHash);  
  305.         if(cert) delete[] cert;  
  306.         return result;  
  307.     }    
  308.     //获取公钥句柄  
  309.     HCRYPTKEY hPubKey;    
  310.     if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))    
  311.     {    
  312.         string errorcode = getErrorCode();  
  313.         Result* result = new Result("Singer.cpp",250,"导入公钥失败!",errorcode.length()==0?"{}":errorcode);  
  314.         log->error("Signer.cpp 308 CryptImportPublicKeyInfo")->error(errorcode);  
  315.         if(signedData) delete[] signedData;  
  316.         if(hProv) CryptReleaseContext(hProv,0);  
  317.         if(orgBlob) delete[] orgBlob;  
  318.         if(hHash) CryptDestroyHash(hHash);  
  319.         if(cert) delete[] cert;  
  320.         if(pCertContext) CryptReleaseContext(hProv,0);  
  321.         return result;  
  322.     }    
  323.     //验证签名  
  324.     if(!CryptVerifySignature(hHash, signedData, length, hPubKey, NULL, 0))    
  325.     {    
  326.         string errorcode = getErrorCode();  
  327.         Result* result = new Result("Singer.cpp",257,"验证签名失败!",errorcode.length()==0?"{}":errorcode);  
  328.         log->error("Signer.cpp 322 CryptVerifySignature")->error(errorcode);  
  329.         if(signedData) delete[] signedData;  
  330.         if(hProv) CryptReleaseContext(hProv,0);  
  331.         if(orgBlob) delete[] orgBlob;  
  332.         if(hHash) CryptDestroyHash(hHash);  
  333.         if(cert) delete[] cert;  
  334.         if(pCertContext) CertFreeCertificateContext(pCertContext);  
  335.         if(hPubKey) CryptDestroyKey(hPubKey);    
  336.         return result;  
  337.     }    
  338.   
  339.     //释放内存  
  340.     if(signedData) delete[] signedData;  
  341.     if(hProv) CryptReleaseContext(hProv,0);  
  342.     if(orgBlob) delete[] orgBlob;  
  343.     if(hHash) CryptDestroyHash(hHash);  
  344.     if(cert) delete[] cert;  
  345.     if(pCertContext) CertFreeCertificateContext(pCertContext);  
  346.     if(hPubKey) CryptDestroyKey(hPubKey);    
  347.   
  348.     Result* result = new Result(org_text);  
  349.     return result;    
  350. }  



-------------------------改版分割线---------------------------------------------
以下代码只做示例,还存在许多问题需要修改
签名与验证(分验证证书合法性与不验证证书两种验证签名)
[cpp]  view plain  copy
 print ?
  1. <span style="font-size:13px;">#include <stdio.h>  
  2. #include <conio.h>  
  3. #include <windows.h>  
  4. #include <wincrypt.h>  
  5. #include <iostream>  
  6. #include "Base.h"   //实现Base64转码  
  7. #include <comdef.h>  
  8.   
  9. using namespace std;  
  10. #define TEST_CSP_NAME    "FEITIAN ePassNG RSA Cryptographic Service Provider" //飞天CSP  
  11.   
  12. //返回值为'签名base64码'和';'和'证书base64码'  
  13. STDMETHODIMP CSignedData::Sign(BSTR orgData, BSTR* signature)  
  14. {  
  15.     // TODO: Add your implementation code here  
  16.     string orgText = _bstr_t (orgData);  
  17.     // 准备数据  
  18.     HCRYPTPROV hProv;  
  19.     //  --------------------------------------------------------------------  
  20.     // get the CSP handle  
  21.     printf("The following phase of this program is signature.\n\n");  
  22.     if(CryptAcquireContext(  
  23.         &hProv,   
  24.         NULL,   
  25.         TEST_CSP_NAME,  
  26.         PROV_RSA_FULL,   
  27.         0))   
  28.     {  
  29.         printf("CSP context acquired.\n");  
  30.     }  
  31.     else    //create if not exist  
  32.     {  
  33.         if(CryptAcquireContext(  
  34.             &hProv,   
  35.             NULL,   
  36.             TEST_CSP_NAME,   
  37.             PROV_RSA_FULL,   
  38.             CRYPT_NEWKEYSET))   
  39.         {  
  40.             printf("A new key container has been created.\n");  
  41.         }  
  42.         else  
  43.         {  
  44.         }  
  45.     }  
  46.   
  47.     // 打开证书库  
  48.     HCERTSTORE hCertStore = CertOpenStore(  
  49.         CERT_STORE_PROV_SYSTEM,   // The store provider type.  
  50.         0,                        // The encoding type is not needed.  
  51.         hProv,               // Use the epassNG HCRYPTPROV.  
  52.         CERT_SYSTEM_STORE_CURRENT_USER,  
  53.         L"MY"  
  54.         );  
  55.     if(hCertStore == NULL)  
  56.     {  
  57.   
  58.     }  
  59.   
  60.     // 查找证书  
  61.     PCCERT_CONTEXT hCert = CertFindCertificateInStore(  
  62.         hCertStore,  
  63.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,  
  64.         0,  
  65.         CERT_FIND_SUBJECT_STR,  
  66.         L"周绍禹",  
  67.         NULL);  
  68.     if(hCert == NULL)  
  69.     {  
  70.   
  71.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  72.         return E_FAIL;  
  73.     }  
  74.   
  75.   
  76.     /**//* 
  77.         BOOL WINAPI CryptAcquireCertificatePrivateKey( 
  78.         __in          PCCERT_CONTEXT pCert, 
  79.         __in          DWORD dwFlags, 
  80.         __in          void* pvReserved, 
  81.         __out         HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey, 
  82.         __out         DWORD* pdwKeySpec, 
  83.         __out         BOOL* pfCallerFreeProvOrNCryptKey 
  84.         ); 
  85.         */  
  86.     // 请求证书私钥服务  
  87.     HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;  
  88.     DWORD dwKeyType = 0;  
  89.     BOOL bFreeKeyProv = FALSE;  
  90.     if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))  
  91.     {  
  92.   
  93.         CertFreeCertificateContext(hCert);  
  94.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  95.     }  
  96.   
  97.     // 创建离散对象  
  98.     HCRYPTHASH hHash = NULL;  
  99.     if(!CryptCreateHash(  
  100.         hKeyProv,                    // 容器句柄   
  101.         CALG_MD5,                    // 算法标识  
  102.         NULL,                        // 算法使用的Key  
  103.         0,                            // 算法标识  
  104.         &hHash))                    // 返回的HASH对象  
  105.     {  
  106.   
  107.         CertFreeCertificateContext(hCert);  
  108.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  109.     }  
  110.     BYTE *orgTextByte ;  
  111.     int orgTextLen = orgText.size();  
  112.     orgTextByte = new BYTE[orgTextLen];  
  113.     for(int i=0;i<orgTextLen;i++){  
  114.         orgTextByte[i]=orgText[i];  
  115.     }  
  116.     orgTextByte[orgTextLen]='\0';  
  117.     // 计算数据摘要  
  118.     if(CryptHashData(hHash, orgTextByte, orgTextLen, 0) == 0)  
  119.     {  
  120.   
  121.         CryptDestroyHash(hHash);   
  122.         CryptReleaseContext(hKeyProv, 0);  
  123.         CertFreeCertificateContext(hCert);  
  124.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  125.     }  
  126.   
  127.     /**//* 
  128.         BOOL WINAPI CryptSignHash( 
  129.         __in          HCRYPTHASH hHash, 
  130.         __in          DWORD dwKeySpec, 
  131.         __in          LPCTSTR sDescription, 
  132.         __in          DWORD dwFlags, 
  133.         __out         BYTE* pbSignature, 
  134.         __in_out      DWORD* pdwSigLen 
  135.         ); 
  136.         */  
  137.   
  138.     DWORD cbSign = 4096;  
  139.     BYTE  *pbSign;  
  140.     //获取签名数据摘要大小  
  141.     if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))  
  142.     {  
  143.   
  144.         CryptDestroyHash(hHash);   
  145.         CryptReleaseContext(hKeyProv, 0);  
  146.         CertFreeCertificateContext(hCert);  
  147.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  148.     }  
  149.     pbSign = new BYTE[cbSign];  
  150.     //签名数据摘要  
  151.     if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))  
  152.     {  
  153.   
  154.         CryptDestroyHash(hHash);   
  155.         CryptReleaseContext(hKeyProv, 0);  
  156.         CertFreeCertificateContext(hCert);  
  157.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  158.     }  
  159.     cout<<base64_encode(pbSign,cbSign)<<endl;  
  160.     //将签名值转成base64编码  
  161.     string baseSign = base64_encode(pbSign,cbSign);  
  162.     //获取证书的base64编码  
  163.     BYTE *newCert;  
  164.     newCert = new BYTE[hCert->cbCertEncoded];  
  165.     newCert = hCert->pbCertEncoded;  
  166.     string baseCert = base64_encode(newCert,hCert->cbCertEncoded);  
  167.     //返回签名和证书的base64编码  
  168.     CComBSTR bstr((baseSign+";"+baseCert).c_str());  
  169.     *signature=bstr;  
  170.     //释放资源  
  171.     if(hHash != NULL)  
  172.     {  
  173.         CryptDestroyHash(hHash);   
  174.         hHash = NULL;  
  175.     }  
  176.   
  177.     if(hKeyProv != NULL && bFreeKeyProv)  
  178.     {  
  179.         CryptReleaseContext(hKeyProv, 0);  
  180.         hKeyProv = NULL;  
  181.     }  
  182.   
  183.     if(hCert != NULL)  
  184.     {  
  185.         CertFreeCertificateContext(hCert);  
  186.         hCert = NULL;  
  187.     }  
  188.   
  189.     if(hCertStore != NULL)  
  190.     {  
  191.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  192.         hCertStore = NULL;  
  193.     }  
  194.   
  195.     return S_OK;  
  196. }  
  197.   
  198. //验证签名(无证书验证)  
  199. STDMETHODIMP CSignedData::VerifySign(BSTR Signed_base64, BSTR Cert_base64, BSTR orgData, BOOL* verifySuc)  
  200. {  
  201.     // TODO: Add your implementation code here  
  202.     // 准备数据  
  203.     BYTE* signedData;  
  204.     string cstrSigned = _bstr_t (Signed_base64);  
  205.     string decodeData = base64_decode(cstrSigned);  
  206.     int len = decodeData.size();  
  207.     signedData = new BYTE[len] ;  
  208.     for(int i = 0; i < len; ++i)  
  209.     {  
  210.         signedData[i] = (byte)decodeData[i];  
  211.     }  
  212.     signedData[len] = '\0';  
  213.     // 请求容器服务  
  214.     HCRYPTPROV hProv = NULL;   
  215.     if(!CryptAcquireContext(  
  216.         &hProv,                // 返回的句柄  
  217.         NULL,                // CSP key 容器名称  
  218.         TEST_CSP_NAME,                // CSP 提供者名称  
  219.         PROV_RSA_FULL,        // CSP 提供者类型  
  220.         0))                    // 附加参数  
  221.     {  
  222.   
  223.         return E_FAIL;  
  224.     }  
  225.   
  226.     // 创建离散对象  
  227.     HCRYPTHASH hHash = NULL;  
  228.     if(!CryptCreateHash(  
  229.         hProv,                        // 容器句柄   
  230.         CALG_MD5,                    // 算法标识  
  231.         NULL,                        // 算法使用的Key  
  232.         0,                            // 算法标识  
  233.         &hHash))                    // 返回的HASH对象  
  234.     {  
  235.   
  236.   
  237.         CryptReleaseContext(hProv, 0);  
  238.         return E_FAIL;  
  239.     }  
  240.     string cstrOrgData = _bstr_t (orgData);  
  241.     BYTE* orgBlob;  
  242.     int orglen = cstrOrgData.size();  
  243.     orgBlob = new BYTE[orglen] ;  
  244.     for(int i = 0; i < orglen; ++i)  
  245.     {  
  246.         orgBlob[i] = (byte)cstrOrgData[i];  
  247.     }  
  248.     orgBlob[orglen] = '\0';  
  249.     // 计算数据摘要  
  250.     if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)  
  251.     {  
  252.   
  253.   
  254.         CryptDestroyHash(hHash);   
  255.         CryptReleaseContext(hProv, 0);  
  256.         return E_FAIL;  
  257.     }  
  258.   
  259.     // 获取签名者证书公钥  
  260.     /* 
  261.     HCERTSTORE WINAPI CertOpenStore( 
  262.     __in          LPCSTR lpszStoreProvider, 
  263.     __in          DWORD dwMsgAndCertEncodingType, 
  264.     __in          HCRYPTPROV_LEGACY hCryptProv, 
  265.     __in          DWORD dwFlags, 
  266.     __in          const void* pvPara 
  267.     ); 
  268.     */  
  269.     BYTE* cert;  
  270.     string cstrCert_base64 = _bstr_t (Cert_base64);  
  271.     string decodeCert = base64_decode(cstrCert_base64);  
  272.     int certLen = decodeCert.size();  
  273.     cert = new BYTE[certLen] ;  
  274.     for(int i = 0; i < certLen; ++i)  
  275.     {  
  276.         cert[i] = (byte)decodeCert[i];  
  277.     }  
  278.     cert[certLen] = '\0';  
  279.     PCCERT_CONTEXT  pCertContext = NULL;  
  280.     if(pCertContext = CertCreateCertificateContext(  
  281.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,              // The encoding type  
  282.         cert,   // The encoded data from  
  283.         // the certificate retrieved  
  284.         certLen))  // The length of the encoded data  
  285.     {  
  286.         printf("A new certificate has been created.\n");  
  287.   
  288.         // Use the certificate context as needed.  
  289.         // ...  
  290.     }  
  291.     else  
  292.     {  
  293.         printf("A new certificate could not be created.\n");  
  294.         return E_FAIL;  
  295.     }  
  296.     HCRYPTKEY hPubKey;  
  297.     if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))  
  298.     {  
  299.         CryptDestroyKey(hPubKey);  
  300.         CryptReleaseContext(hProv, 0);  
  301.         return E_FAIL;  
  302.     }  
  303.     // 校验签名  
  304.     /* 
  305.     BOOL WINAPI CryptVerifySignature( 
  306.     __in          HCRYPTHASH hHash, 
  307.     __in          BYTE* pbSignature, 
  308.     __in          DWORD dwSigLen, 
  309.     __in          HCRYPTKEY hPubKey, 
  310.     __in          LPCTSTR sDescription, 
  311.     __in          DWORD dwFlags 
  312.     ); 
  313.     */  
  314.     if(!CryptVerifySignature(hHash, signedData, len, hPubKey, NULL, 0))  
  315.     {  
  316.         *verifySuc=false;  
  317.         return S_FALSE;  
  318.     }  
  319.     else  
  320.     {  
  321.         *verifySuc=true;  
  322.     }  
  323.   
  324.     // 释放获取的对象  
  325.     if(hPubKey != NULL)  
  326.     {  
  327.         CryptDestroyKey(hPubKey);  
  328.         hPubKey = NULL;  
  329.     }  
  330.   
  331.     if(hHash != NULL)  
  332.     {  
  333.         CryptDestroyHash(hHash);   
  334.         hHash = NULL;  
  335.     }  
  336.   
  337.     if(pCertContext != NULL)  
  338.     {  
  339.         CertFreeCertificateContext(pCertContext);  
  340.         pCertContext = NULL;  
  341.     }  
  342.   
  343.   
  344.     if(hProv != NULL)  
  345.     {  
  346.         CryptReleaseContext(hProv, 0);  
  347.         hProv = NULL;  
  348.     }  
  349.     return S_OK;  
  350. }  
  351.   
  352. //带证书验证部分的签名验证  
  353. STDMETHODIMP CSignedData::VerifySignWithCRL(BSTR Signed_base64, BSTR Cert_base64, BSTR orgData, BSTR CRL_base64, BOOL* verifySuc)  
  354. {  
  355.     // TODO: 在此添加实现代码  
  356.     // TODO: Add your implementation code here  
  357.     // 准备数据  
  358.     BYTE* signedData;  
  359.     string cstrSigned = _bstr_t (Signed_base64);  
  360.     string cstrCRL_base64 = _bstr_t(CRL_base64);  
  361.     int count  = cstrCRL_base64.size();  
  362.     string decodeData = base64_decode(cstrSigned);  
  363.     int len = decodeData.size();  
  364.     signedData = new BYTE[len] ;  
  365.     for(int i = 0; i < len; ++i)  
  366.     {  
  367.         signedData[i] = (byte)decodeData[i];  
  368.     }  
  369.     signedData[len] = '\0';  
  370.     // 请求容器服务  
  371.     HCRYPTPROV hProv = NULL;   
  372.     if(!CryptAcquireContext(  
  373.         &hProv,                // 返回的句柄  
  374.         NULL,                // CSP key 容器名称  
  375.         TEST_CSP_NAME,                // CSP 提供者名称  
  376.         PROV_RSA_FULL,        // CSP 提供者类型  
  377.         0))                    // 附加参数  
  378.     {  
  379.   
  380.         return E_FAIL;  
  381.     }  
  382.   
  383.     // 创建离散对象  
  384.     HCRYPTHASH hHash = NULL;  
  385.     if(!CryptCreateHash(  
  386.         hProv,                        // 容器句柄   
  387.         CALG_MD5,                    // 算法标识  
  388.         NULL,                        // 算法使用的Key  
  389.         0,                            // 算法标识  
  390.         &hHash))                    // 返回的HASH对象  
  391.     {  
  392.   
  393.   
  394.         CryptReleaseContext(hProv, 0);  
  395.         return E_FAIL;  
  396.     }  
  397.     string cstrOrgData = _bstr_t (orgData);  
  398.     BYTE* orgBlob;  
  399.     int orglen = cstrOrgData.size();  
  400.     orgBlob = new BYTE[orglen] ;  
  401.     for(int i = 0; i < orglen; ++i)  
  402.     {  
  403.         orgBlob[i] = (byte)cstrOrgData[i];  
  404.     }  
  405.     orgBlob[orglen] = '\0';  
  406.     // 计算数据摘要  
  407.     if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)  
  408.     {  
  409.   
  410.   
  411.         CryptDestroyHash(hHash);   
  412.         CryptReleaseContext(hProv, 0);  
  413.         return E_FAIL;  
  414.     }  
  415.   
  416.     // 获取签名者证书公钥  
  417.     /* 
  418.     HCERTSTORE WINAPI CertOpenStore( 
  419.     __in          LPCSTR lpszStoreProvider, 
  420.     __in          DWORD dwMsgAndCertEncodingType, 
  421.     __in          HCRYPTPROV_LEGACY hCryptProv, 
  422.     __in          DWORD dwFlags, 
  423.     __in          const void* pvPara 
  424.     ); 
  425.     */  
  426.     BYTE* cert;  
  427.     string cstrCert_base64 = _bstr_t (Cert_base64);  
  428.     string decodeCert = base64_decode(cstrCert_base64);  
  429.     int certLen = decodeCert.size();  
  430.     cert = new BYTE[certLen] ;  
  431.     for(int i = 0; i < certLen; ++i)  
  432.     {  
  433.         cert[i] = (byte)decodeCert[i];  
  434.     }  
  435.     cert[certLen] = '\0';  
  436.     PCCERT_CONTEXT  pCertContext = NULL;  
  437.     if(pCertContext = CertCreateCertificateContext(  
  438.         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,              // The encoding type  
  439.         cert,   // The encoded data from  
  440.         // the certificate retrieved  
  441.         certLen))  // The length of the encoded data  
  442.     {  
  443.         printf("A new certificate has been created.\n");  
  444.   
  445.         // Use the certificate context as needed.  
  446.         // ...  
  447.     }  
  448.     else  
  449.     {  
  450.         printf("A new certificate could not be created.\n");  
  451.         return E_FAIL;  
  452.     }  
  453.     bool certIsValid = verifyCert(pCertContext,cstrCRL_base64);  
  454.     if(certIsValid){  
  455.   
  456.         HCRYPTKEY hPubKey;  
  457.         if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))  
  458.         {  
  459.             CryptDestroyKey(hPubKey);  
  460.             CryptReleaseContext(hProv, 0);  
  461.             return E_FAIL;  
  462.         }  
  463.         // 校验签名  
  464.         /* 
  465.         BOOL WINAPI CryptVerifySignature( 
  466.         __in          HCRYPTHASH hHash, 
  467.         __in          BYTE* pbSignature, 
  468.         __in          DWORD dwSigLen, 
  469.         __in          HCRYPTKEY hPubKey, 
  470.         __in          LPCTSTR sDescription, 
  471.         __in          DWORD dwFlags 
  472.         ); 
  473.         */  
  474.         if(!CryptVerifySignature(hHash, signedData, len, hPubKey, NULL, 0))  
  475.         {  
  476.             *verifySuc=false;  
  477.             return S_FALSE;  
  478.         }  
  479.         else  
  480.         {  
  481.             *verifySuc=true;  
  482.         }     
  483.         if(hPubKey != NULL)  
  484.         {  
  485.             CryptDestroyKey(hPubKey);  
  486.             hPubKey = NULL;  
  487.         }  
  488.   
  489.     }else{  
  490.         *verifySuc=false;  
  491.     }  
  492.   
  493.     // 释放获取的对象  
  494.   
  495.     if(hHash != NULL)  
  496.     {  
  497.         CryptDestroyHash(hHash);   
  498.         hHash = NULL;  
  499.     }  
  500.   
  501.     if(pCertContext != NULL)  
  502.     {  
  503.         CertFreeCertificateContext(pCertContext);  
  504.         pCertContext = NULL;  
  505.     }  
  506.   
  507.   
  508.     if(hProv != NULL)  
  509.     {  
  510.         CryptReleaseContext(hProv, 0);  
  511.         hProv = NULL;  
  512.     }  
  513.     return S_OK;  
  514. }  
  515.   
  516. // 校验证书合法性  
  517. bool verifyCert(PCCERT_CONTEXT hCert,string CRL_base64)  
  518. {  
  519.     /* 
  520.     *获取CRLContext对象 
  521.     */  
  522.     string CRL = base64_decode(CRL_base64);  
  523.     BYTE *pbCRL = NULL;  
  524.     pbCRL = new BYTE[CRL.size()];  
  525.     for(int i=0;i<CRL.size();i++){  
  526.         pbCRL[i]=(BYTE)CRL[i];  
  527.     }  
  528.     int cbCRL = CRL.size();  
  529.     pbCRL[cbCRL]='\0';  
  530.     PCCRL_CONTEXT hCRL = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pbCRL,cbCRL);  
  531.     if(hCRL==NULL){  
  532.         printf("未找到CRL");  
  533.     }else{  
  534.         printf("找到CRL");  
  535.     }  
  536.     /**//* 
  537.         LONG WINAPI CertVerifyTimeValidity( 
  538.         __in          LPFILETIME pTimeToVerify, 
  539.         __in          PCERT_INFO pCertInfo 
  540.         ); 
  541.         */  
  542.     // 校验证书日期  
  543.     int nRetCode = CertVerifyTimeValidity(NULL, hCert->pCertInfo);  
  544.     if(nRetCode < 0)  
  545.     {  
  546.         printf("Verify cert's date failed: BEFORE date after TODAY!\n");  
  547.         return false;  
  548.     }  
  549.   
  550.     if(nRetCode > 0)  
  551.     {  
  552.         printf("Verify cert's date failed: Cert has expired!\n");  
  553.         return false;  
  554.     }  
  555.   
  556.     if(nRetCode == 0)  
  557.     {  
  558.         printf("Verify cert's date succeed!\n");  
  559.   
  560.     }  
  561.   
  562.     // 校验签名者证书  
  563.   
  564.     HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");  
  565.     if(hCertStore != NULL)  
  566.     {  
  567.         /**//* 
  568.             PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore( 
  569.             __in          HCERTSTORE hCertStore, 
  570.             __in          PCCERT_CONTEXT pSubjectContext, 
  571.             __in_opt      PCCERT_CONTEXT pPrevIssuerContext, 
  572.             __in_out      DWORD* pdwFlags 
  573.             ); 
  574.             */  
  575.         // 2.  
  576.         DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;  
  577.         PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, NULL, &dwFlags);  
  578.         if(hIssuserCert != NULL)  
  579.         {  
  580.             BOOL bCheckOK = FALSE;  
  581.             while(hIssuserCert != NULL)  
  582.             {  
  583.                 /**//* 
  584.                     BOOL WINAPI CertVerifySubjectCertificateContext( 
  585.                     __in          PCCERT_CONTEXT pSubject, 
  586.                     __in_opt      PCCERT_CONTEXT pIssuer, 
  587.                     __in_out      DWORD* pdwFlags 
  588.                     ); 
  589.                     */  
  590.                 // 校验证书签发者信息合法性  
  591.                 dwFlags = CERT_STORE_SIGNATURE_FLAG;  
  592.                 if(CertVerifySubjectCertificateContext(hCert, hIssuserCert, &dwFlags))  
  593.                 {  
  594.                     if(dwFlags == 0)  
  595.                     {  
  596.                         printf("Verify cert by issuser's cert succeed! \n");  
  597.                         bCheckOK = TRUE;  
  598.                         break;  
  599.                     }  
  600.                 }  
  601.                 else  
  602.                 {  
  603.                     printf("Verify cert by issuser's cert failed! \n");  
  604.                     return false;  
  605.                     break;  
  606.                 }  
  607.   
  608.                 // Next ..  
  609.                 hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, hIssuserCert, &dwFlags);  
  610.             }  
  611.   
  612.             if(!bCheckOK)  
  613.             {  
  614.                 printf("Verify cert by issuser's cert failed! \n");  
  615.                 return false;  
  616.             }  
  617.   
  618.         }  
  619.         else  
  620.         {  
  621.             printf("Can not find cert issuser's cert!\n");  
  622.         }  
  623.   
  624.         if(hIssuserCert != NULL)  
  625.         {  
  626.             CertFreeCertificateContext(hIssuserCert);  
  627.             hIssuserCert = NULL;  
  628.         }  
  629.     }  
  630.     else  
  631.     {  
  632.         printf("Open ROOT CertStore failed!\n");  
  633.         return false;  
  634.     }  
  635.   
  636.     if(hCertStore != NULL)  
  637.     {  
  638.         CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);  
  639.         hCertStore = NULL;  
  640.     }  
  641.   
  642.   
  643.     // 校验 CRL 列表  
  644.   
  645.     // 1.  
  646.     //BYTE* pbCrlData = NULL;  
  647.     //DWORD cbCrlData = 0;  
  648.     //readFile("c:\\cfcaT.crl", NULL, cbCrlData);  
  649.     //if(cbCrlData > 0)  
  650.     //{  
  651.     //    pbCrlData = (BYTE*) new char[cbCrlData];  
  652.     //    readFile("c:\\cfcaT.crl", pbCrlData, cbCrlData);  
  653.     //}  
  654.   
  655.     ///**//*  
  656.     //    PCCRL_CONTEXT WINAPI CertCreateCRLContext(  
  657.     //    __in          DWORD dwCertEncodingType,  
  658.     //    __in          const BYTE* pbCrlEncoded,  
  659.     //    __in          DWORD cbCrlEncoded  
  660.     //    );  
  661.     //    */  
  662.   
  663.      2.转换CRL数据为CRL句柄  
  664.     //PCCRL_CONTEXT hCRL = CertCreateCRLContext(MY_ENCODING_TYPE, pbCrlData, cbCrlData);  
  665.     //delete [] pbCrlData;  
  666.     if(hCRL != NULL)  
  667.     {  
  668.         /**//* 
  669.             BOOL WINAPI CertIsValidCRLForCertificate( 
  670.             __in          PCCERT_CONTEXT pCert, 
  671.             __in          PCCRL_CONTEXT pCRL, 
  672.             __in          DWORD dwFlags, 
  673.             __in          void* pvReserved 
  674.             */  
  675.         if(CertIsValidCRLForCertificate(hCert, hCRL, 0, NULL))  
  676.         {  
  677.             printf("CRL is valid for the cert!\n");  
  678.         }  
  679.         else  
  680.         {  
  681.             printf("CRL is invalid for the cert!!\n");  
  682.             return false;  
  683.         }  
  684.   
  685.         /**//* 
  686.             BOOL WINAPI CertFindCertificateInCRL( 
  687.             __in          PCCERT_CONTEXT pCert, 
  688.             __in          PCCRL_CONTEXT pCrlContext, 
  689.             __in          DWORD dwFlags, 
  690.             __in_opt      void* pvReserved, 
  691.             __out         PCRL_ENTRY* pCrlEntry 
  692.             ); 
  693.             */  
  694.         // Step 4: 检查CRL是否包含该证书  
  695.         PCRL_ENTRY pCrlEntry = NULL;  
  696.         if(CertFindCertificateInCRL(hCert, hCRL, 0, 0, &pCrlEntry))  
  697.         {  
  698.             if(pCrlEntry != NULL)  
  699.             {  
  700.                 printf("Cert has been revoked!\n");  
  701.                 return false;  
  702.             }  
  703.             else  
  704.             {  
  705.                 printf("Cert not be revoked!\n");  
  706.             }  
  707.         }  
  708.         else  
  709.         {  
  710.             printf("Find cert in CRL failed!\n");  
  711.             return false;  
  712.         }  
  713.     }  
  714.     else  
  715.     {  
  716.         printf("Create CRL context failed!\n");  
  717.         return false;  
  718.     }  
  719.   
  720.     if(hCRL != NULL)  
  721.     {  
  722.         CertFreeCRLContext(hCRL);  
  723.     }  
  724. } </span>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值