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

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

代码有待修改

信封加密与解密

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

编写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 ? /* * * * 文件名称:Sig ...

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

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

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

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

  5. ActiveX控件开发总结(续二)

    开发过程中一些经验总结 以下总结主要由李俊峰(lijunfeng 00165774/huawei,).李伟(liwei 00165242/huawei,).姜川(j00132245)总结 1.自定义C ...

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

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

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

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

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

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

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

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

最新文章

  1. SEH反调试(SetUnhandledExceptionFilter)
  2. 【数字图像处理】Canny边缘检测详解及编程实现
  3. 【前端】VUE UI的安装
  4. linux安装oracle
  5. video safari不支持吗_您支持吗? 公园遛狗纳入 “不文明行为黑名单”
  6. 第八周项目4-个人所得税计算器
  7. html字体兼容写法,字体兼容写法
  8. wps日期加减算天数_日期相减之后的天数怎么用公式计算 - 卡饭网
  9. Spartan-6 FPGA 如何使用ISE下载程序
  10. java 表头固定_常用的固定表头的几种做法
  11. linux硬链接与软链接的联系与区别
  12. vue后端模板、vue登录界面、注册界面(带短信验证码)模板
  13. 开发基于地图的火车站点查询系统
  14. 怎样给电脑文件夹批量快速重新命名?
  15. C++ 汇编代码分析——递归函数调用、浮点数比较、选择语句
  16. Educational Codeforces Round 40千名记
  17. 微信小程序输入框input
  18. Bootstrap-30分钟就能上手的Bootstrap教程【史上最全】
  19. 宿命之战:程序员VS产品经理
  20. kafka删除队列_Kafka消息队列

热门文章

  1. 华为荣耀note10计算机在哪找,华为荣耀note10如何使用电脑模式-华为云电脑使用方法介绍 - Iefans...
  2. 乐信季报图解:交易额达562亿 利润4.1亿环比增长59%
  3. Leetcode刷题笔记——剑指 Offer 46. 把数字翻译成字符串(中等)
  4. 官宣 加速科技与思特威联合开发高速图像采集测试系统
  5. 上了 istio 的贼船之 API Gateway
  6. 20190912-1 每周例行报告
  7. 【Why】物理内存与虚拟内存区别与联系
  8. #define xxx后面啥都不跟是什么意思
  9. ajax的常用api测试
  10. 核查清单-小程序分享功能