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

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

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

  1. 编写ATL工程实现ActiveX控件调用cryptoAPI接口(三)------------AES对称加密与解密

    注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出. [cpp]  view plain  copy  print ? /* * * * 文件名称:Enc ...

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

    注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出. [cpp]  view plain  copy  print ? /* * * * 文件名称:Env ...

  3. 使用ATL创建简单ActiveX控件(一) —— 创建ATL项目

    创建过程以VS2010为例,分三篇(创建ATL项目.添加方法/属性和枚举.添加连接点)演示.本篇演示创建ATL项目. 传送门: <使用ATL创建简单ActiveX控件(二) -- 添加方法/属性 ...

  4. 如何在VB中实现ActiveX控件的IobjectSafety接口

    如何在VB中实现ActiveX控件的IobjectSafety接口 ------------------------------------------------------------------ ...

  5. 关于vlc播放器的ActiveX控件调用问题

    下了好几个版本的vlc播放器,却发现vlc播放器自带的ActiveX插件除了初始化能用之外,后面的js接口完全用不了 从1.0.5版本之后的ActiveX无法调用第一版的js接口 从2.0.5版本之后 ...

  6. 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题

    程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...

  7. ie浏览器java 脚本下载_如何设置ie浏览器中的activex控件和插件java脚本下载用户验证...

    ActiveX是Microsoft提出的一组使用COM(ComponentObjectModel,部件对象模型)使得软件部件在网络环境中进行交互的技术集.它与具体的编程语言无关.作为针对Interne ...

  8. VS创建ATL项目,ActiveX控件

    1. 前言 最近一直在做浏览器控件相关,面向IE浏览器.虽然IE有各种缺点,但是还是有很多项目是基于IE的.呃呃呃,比如需要与硬件交互,可以需要多个控件配合,最起码我遇到了(签名控件VCTK和一些远程 ...

  9. [转]ASP中ActiveX控件的内嵌及调用

    懂ASP(Active Server Pages)的人很多,但能用ASP自如地调用ActiveX控件的人却不多:如果不调用ActiveX控件,则可以说微软当初设计ASP的初衷根本没有达到.众所周知,A ...

最新文章

  1. Jenkins分布式部署配置
  2. python整数类型在每一台计算机上的取值范围是一样的_第四章、Python数据类型
  3. hdu 5606(并查集)
  4. python调用可执行文件
  5. vue监听路由的变化,跳转到同一个页面时,Url改变但视图未重新加载问题
  6. linux验证db2安装成功_DB2(Linux 64位)安装教程
  7. PCB板设计流程有哪些?
  8. resin设置权限_resin加固
  9. 20182319彭淼迪 2019-2020-1 《数据结构与面向对象程序设计》实验一报告
  10. 【源码】林业害虫检测小程序(可拓展美化)
  11. 应用交付能给客户带来什么价值?
  12. Python简单GUI(模拟放大镜)
  13. TCP三次握手原理详解
  14. mac定时执行python_Mac中的定时任务利器:launchctl
  15. Linux企业级服务之实现DNS子域服务器
  16. 告别盗版杀软!免费用17款鼎鼎大名的杀毒软件
  17. IOS 通过麦克风检测声音分贝
  18. 书单 | 本本经典,学算法就从这里选了!
  19. 为什么打印机显示服务器脱机,为什么打印机显示服务器脱机
  20. 视频教程-【吴刚】技术答疑与项目讲评视频教程(随时更新)-UI

热门文章

  1. Docker+NETCore系列文章(三、Docker常用命令)
  2. Altium Designer 20 如何快速给不规则板框铺铜的方法,超级简单操作!
  3. 欧科云链接受北京电视台采访:以创新科技助力《反电信网络诈骗法》实施
  4. 如何实现html5页面,自动提示添加到主屏幕
  5. 单片机中c语言 右移 和左移 与CY
  6. html格式字体颜色入门(颜色表格查询)
  7. 商业研究(9):入口思维(刚需、频次、免费、变现)
  8. arch linux u盘安装,从U盘安装archlinux-2009.08完整过程 - Leo's Utopia
  9. 【Lua进阶系列】lua元方法
  10. python脚本无缝拼接图片