编写ATL工程实现ActiveX控件调用cryptoAPI接口(一)------------签名与验证
注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出.
- /*
- *
- *
- * 文件名称:Signer.cpp
- * 摘 要:
- * 数字签名及验证
- * 当前版本:1.0
- * 作 者:周绍禹
- * 创建日期:2012年3月4日
- */
- #include "StdAfx.h"
- #include "Signer.h"
- #include "Map.h"
- #include "generic.h"
- #include "base64.h"
- Signer::Signer():CSP_NAME(FEITIAN_CSP_NAME)
- {
- log = new Log("Signer");
- certMsg = new CertMsg();
- }
- Signer::~Signer()
- {
- if(log) delete log;
- if(certMsg) delete certMsg;
- }
- //-----------------------------------------------------------
- // 函数名称:
- // sign
- // 参数:
- // - string plain_text 明文
- // - BYTE* target_SN_blob 目标证书的序列号字节数组
- // - int cblob 目标证书的序列号字节数组大小
- // 返回:
- // Result*
- // 说明:
- // 通过指定的序列号查找证书以及私钥,对数据做数字签名操作
- //-----------------------------------------------------------
- Result* Signer::sign(string plain_text,BYTE* target_SN_blob,int cblob)
- {
- // 准备数据
- HCRYPTPROV hProv;
- if(!CryptAcquireContext(&hProv,
- NULL,
- CSP_NAME,
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- {
- DWORD dwLastErr = GetLastError();
- if(NTE_BAD_KEYSET == dwLastErr)
- {
- Result* result = new Result("Signer.cpp",20,"密钥库不存在,或者访问被拒绝!","{}");
- return result;
- }
- else{
- if(!CryptAcquireContext(&hProv,
- NULL,
- this->CSP_NAME,
- PROV_RSA_FULL,
- CRYPT_NEWKEYSET))
- {
- Map* map = new Map(1);
- map->put("errcode",dwLastErr);
- string errcode = map->toString();
- delete map;
- Result* result = new Result("Signer.cpp",34,"密钥库已存在,创建密钥库失败!",errcode);
- return result;
- }
- }
- }
- // 请求证书私钥服务
- HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
- DWORD dwKeyType = 0;
- Result* result = certMsg->acquirePrivateKey(hProv,target_SN_blob,cblob,&hKeyProv,&dwKeyType);
- if(!result->isSuccess())
- {
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- log->error("Signer.cpp 86 acquirePrivateKey")->error(getErrorCode());
- return result;
- }
- if(hKeyProv==NULL)
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Signer.cpp",57,"获取私钥服务失败!",errorcode.length()==0?"{}":errorcode);
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- log->error("Signer.cpp 86 acquirePrivateKey")->error(errorcode);
- return result;
- }
- // 创建离散对象
- HCRYPTHASH hHash = NULL;
- if(!CryptCreateHash(
- hKeyProv, // 容器句柄
- CALG_MD5, // 算法标识
- NULL, // 算法使用的Key
- 0, // 算法标识
- &hHash)) // 返回的HASH对象
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Singer.cpp",73,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 102 CryptCreateHash")->error(errorcode);
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- if(hKeyProv != NULL)
- CryptReleaseContext(hKeyProv, 0);
- return result;
- }
- BYTE *orgTextByte ;
- int orgTextLen = plain_text.size();
- orgTextByte = new BYTE[orgTextLen + 1];
- for(int i=0;i<orgTextLen;i++){
- orgTextByte[i]=plain_text[i];
- }
- orgTextByte[orgTextLen]='\0';
- // 计算数据摘要
- if(!CryptHashData(hHash, orgTextByte, orgTextLen, 0))
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Signer.cpp",94,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 128 CryptHashData")->error(errorcode);
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- if(hKeyProv != NULL)
- CryptReleaseContext(hKeyProv, 0);
- if(hHash)
- CryptDestroyHash(hHash);
- if(orgTextByte) delete[] orgTextByte;
- return result;
- }
- DWORD cbSign = 4096;
- BYTE *pbSign;
- //获取签名数据摘要大小
- if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Signer.cpp",106,"获取签名大小失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 147 CryptSignHash")->error(errorcode);
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- if(hKeyProv != NULL)
- CryptReleaseContext(hKeyProv, 0);
- if(hHash)
- CryptDestroyHash(hHash);
- if(orgTextByte) delete[] orgTextByte;
- return result;
- }
- pbSign = new BYTE[cbSign];
- //签名数据摘要
- if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Signer.cpp",116,"签名失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 163 CryptSignHash")->error(errorcode);
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- if(hKeyProv != NULL)
- CryptReleaseContext(hKeyProv, 0);
- if(hHash)
- CryptDestroyHash(hHash);
- if(orgTextByte) delete[] orgTextByte;
- if(pbSign) delete[] pbSign;
- return result;
- }
- //将签名值转成base64编码
- string baseSign = Base64::base64_encode(pbSign,cbSign);
- log->info("----------------------")->info("签名值:")->info(baseSign);
- if(hProv != NULL)
- CryptReleaseContext(hProv, 0);
- if(hKeyProv != NULL)
- CryptReleaseContext(hKeyProv, 0);
- if(hHash)
- CryptDestroyHash(hHash);
- if(orgTextByte) delete[] orgTextByte;
- if(pbSign) delete[] pbSign;
- Result* sign_result = new Result(baseSign);
- return sign_result;
- }
- //-----------------------------------------------------------
- // 函数名称:
- // verify
- // 参数:
- // - string signed_text_base64 签名值base64码
- // - string cert_base64 数字证书base64码
- // - string org_text 明文
- // 返回:
- // Result*
- // 说明:
- // 使用传入的证书base64码创建证书上下文,然后使用该证书及其公钥验证数字签名
- //-----------------------------------------------------------
- Result* Signer::verify(string signed_text_base64,string cert_base64,string org_text)
- {
- BYTE* signedData;
- int length;
- signedData = Base64::base64_decode(signed_text_base64,length);
- // 请求容器服务
- HCRYPTPROV hProv = NULL;
- if(!CryptAcquireContext(&hProv,
- NULL,
- CSP_NAME,
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- {
- DWORD dwLastErr = GetLastError();
- if(signedData) delete[] signedData;
- if(NTE_BAD_KEYSET == dwLastErr)
- {
- Result* result = new Result("Signer.cpp",164,"密钥库不存在,或者访问被拒绝!","{}");
- return result;
- }
- else{
- if(!CryptAcquireContext(&hProv,
- NULL,
- this->CSP_NAME,
- PROV_RSA_FULL,
- CRYPT_NEWKEYSET))
- {
- Map* map = new Map(1);
- map->put("errcode",dwLastErr);
- string errcode = map->toString();
- delete map;
- Result* result = new Result("Signer.cpp",178,"密钥库已存在,创建密钥库失败!",errcode);
- return result;
- }
- }
- }
- // 创建离散对象
- HCRYPTHASH hHash = NULL;
- if(!CryptCreateHash(
- hProv, // 容器句柄
- CALG_MD5, // 算法标识
- NULL, // 算法使用的Key
- 0, // 算法标识
- &hHash)) // 返回的HASH对象
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Singer.cpp",196,"创建HASH失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 248 CryptCreateHash")->error(errorcode);
- if(signedData) delete[] signedData;
- if(hProv) CryptReleaseContext(hProv,0);
- return result;
- }
- BYTE* orgBlob;
- int orglen = org_text.size();
- orgBlob = new BYTE[orglen + 1] ;
- for(int i = 0; i < orglen; ++i)
- {
- orgBlob[i] = (byte)org_text[i];
- }
- orgBlob[orglen] = '\0';
- // 计算数据摘要
- if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Singer.cpp",216,"计算摘要失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 271 CryptHashData")->error(errorcode);
- if(signedData) delete[] signedData;
- if(hProv) CryptReleaseContext(hProv,0);
- if(orgBlob) delete[] orgBlob;
- if(hHash) CryptDestroyHash(hHash);
- return result;
- }
- // 获取签名者证书公钥
- BYTE* cert;
- int len;
- cert = Base64::base64_decode(cert_base64,len);
- char* len_log_str = new char[20];
- itoa(len,len_log_str,10);
- log->info("-----------------------")->info("Signer.cpp 290 CertCreateCertificateContext")->info(cert_base64)->info(len_log_str);
- PCCERT_CONTEXT pCertContext = NULL;
- pCertContext = CertCreateCertificateContext(
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- cert,
- len) ;
- if(pCertContext == NULL)
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Singer.cpp",238,"创建证书上下文失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 290 CertCreateCertificateContext")->error(errorcode);
- if(signedData) delete[] signedData;
- if(hProv) CryptReleaseContext(hProv,0);
- if(orgBlob) delete[] orgBlob;
- if(hHash) CryptDestroyHash(hHash);
- if(cert) delete[] cert;
- return result;
- }
- //获取公钥句柄
- HCRYPTKEY hPubKey;
- if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Singer.cpp",250,"导入公钥失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 308 CryptImportPublicKeyInfo")->error(errorcode);
- if(signedData) delete[] signedData;
- if(hProv) CryptReleaseContext(hProv,0);
- if(orgBlob) delete[] orgBlob;
- if(hHash) CryptDestroyHash(hHash);
- if(cert) delete[] cert;
- if(pCertContext) CryptReleaseContext(hProv,0);
- return result;
- }
- //验证签名
- if(!CryptVerifySignature(hHash, signedData, length, hPubKey, NULL, 0))
- {
- string errorcode = getErrorCode();
- Result* result = new Result("Singer.cpp",257,"验证签名失败!",errorcode.length()==0?"{}":errorcode);
- log->error("Signer.cpp 322 CryptVerifySignature")->error(errorcode);
- if(signedData) delete[] signedData;
- if(hProv) CryptReleaseContext(hProv,0);
- if(orgBlob) delete[] orgBlob;
- if(hHash) CryptDestroyHash(hHash);
- if(cert) delete[] cert;
- if(pCertContext) CertFreeCertificateContext(pCertContext);
- if(hPubKey) CryptDestroyKey(hPubKey);
- return result;
- }
- //释放内存
- if(signedData) delete[] signedData;
- if(hProv) CryptReleaseContext(hProv,0);
- if(orgBlob) delete[] orgBlob;
- if(hHash) CryptDestroyHash(hHash);
- if(cert) delete[] cert;
- if(pCertContext) CertFreeCertificateContext(pCertContext);
- if(hPubKey) CryptDestroyKey(hPubKey);
- Result* result = new Result(org_text);
- return result;
- }
签名与验证(分验证证书合法性与不验证证书两种验证签名)
- <span style="font-size:13px;">#include <stdio.h>
- #include <conio.h>
- #include <windows.h>
- #include <wincrypt.h>
- #include <iostream>
- #include "Base.h" //实现Base64转码
- #include <comdef.h>
- using namespace std;
- #define TEST_CSP_NAME "FEITIAN ePassNG RSA Cryptographic Service Provider" //飞天CSP
- //返回值为'签名base64码'和';'和'证书base64码'
- STDMETHODIMP CSignedData::Sign(BSTR orgData, BSTR* signature)
- {
- // TODO: Add your implementation code here
- string orgText = _bstr_t (orgData);
- // 准备数据
- HCRYPTPROV hProv;
- // --------------------------------------------------------------------
- // get the CSP handle
- printf("The following phase of this program is signature.\n\n");
- if(CryptAcquireContext(
- &hProv,
- NULL,
- TEST_CSP_NAME,
- PROV_RSA_FULL,
- 0))
- {
- printf("CSP context acquired.\n");
- }
- else //create if not exist
- {
- if(CryptAcquireContext(
- &hProv,
- NULL,
- TEST_CSP_NAME,
- PROV_RSA_FULL,
- CRYPT_NEWKEYSET))
- {
- printf("A new key container has been created.\n");
- }
- else
- {
- }
- }
- // 打开证书库
- HCERTSTORE hCertStore = CertOpenStore(
- CERT_STORE_PROV_SYSTEM, // The store provider type.
- 0, // The encoding type is not needed.
- hProv, // Use the epassNG HCRYPTPROV.
- CERT_SYSTEM_STORE_CURRENT_USER,
- L"MY"
- );
- if(hCertStore == NULL)
- {
- }
- // 查找证书
- PCCERT_CONTEXT hCert = CertFindCertificateInStore(
- hCertStore,
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
- 0,
- CERT_FIND_SUBJECT_STR,
- L"周绍禹",
- NULL);
- if(hCert == NULL)
- {
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- return E_FAIL;
- }
- /**//*
- BOOL WINAPI CryptAcquireCertificatePrivateKey(
- __in PCCERT_CONTEXT pCert,
- __in DWORD dwFlags,
- __in void* pvReserved,
- __out HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey,
- __out DWORD* pdwKeySpec,
- __out BOOL* pfCallerFreeProvOrNCryptKey
- );
- */
- // 请求证书私钥服务
- HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyProv = NULL;
- DWORD dwKeyType = 0;
- BOOL bFreeKeyProv = FALSE;
- if(!CryptAcquireCertificatePrivateKey(hCert, 0, 0, &hKeyProv, &dwKeyType, &bFreeKeyProv))
- {
- CertFreeCertificateContext(hCert);
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- }
- // 创建离散对象
- HCRYPTHASH hHash = NULL;
- if(!CryptCreateHash(
- hKeyProv, // 容器句柄
- CALG_MD5, // 算法标识
- NULL, // 算法使用的Key
- 0, // 算法标识
- &hHash)) // 返回的HASH对象
- {
- CertFreeCertificateContext(hCert);
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- }
- BYTE *orgTextByte ;
- int orgTextLen = orgText.size();
- orgTextByte = new BYTE[orgTextLen];
- for(int i=0;i<orgTextLen;i++){
- orgTextByte[i]=orgText[i];
- }
- orgTextByte[orgTextLen]='\0';
- // 计算数据摘要
- if(CryptHashData(hHash, orgTextByte, orgTextLen, 0) == 0)
- {
- CryptDestroyHash(hHash);
- CryptReleaseContext(hKeyProv, 0);
- CertFreeCertificateContext(hCert);
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- }
- /**//*
- BOOL WINAPI CryptSignHash(
- __in HCRYPTHASH hHash,
- __in DWORD dwKeySpec,
- __in LPCTSTR sDescription,
- __in DWORD dwFlags,
- __out BYTE* pbSignature,
- __in_out DWORD* pdwSigLen
- );
- */
- DWORD cbSign = 4096;
- BYTE *pbSign;
- //获取签名数据摘要大小
- if(!CryptSignHash(hHash, dwKeyType, NULL, 0, NULL, &cbSign))
- {
- CryptDestroyHash(hHash);
- CryptReleaseContext(hKeyProv, 0);
- CertFreeCertificateContext(hCert);
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- }
- pbSign = new BYTE[cbSign];
- //签名数据摘要
- if(!CryptSignHash(hHash, dwKeyType, NULL, 0, pbSign, &cbSign))
- {
- CryptDestroyHash(hHash);
- CryptReleaseContext(hKeyProv, 0);
- CertFreeCertificateContext(hCert);
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- }
- cout<<base64_encode(pbSign,cbSign)<<endl;
- //将签名值转成base64编码
- string baseSign = base64_encode(pbSign,cbSign);
- //获取证书的base64编码
- BYTE *newCert;
- newCert = new BYTE[hCert->cbCertEncoded];
- newCert = hCert->pbCertEncoded;
- string baseCert = base64_encode(newCert,hCert->cbCertEncoded);
- //返回签名和证书的base64编码
- CComBSTR bstr((baseSign+";"+baseCert).c_str());
- *signature=bstr;
- //释放资源
- if(hHash != NULL)
- {
- CryptDestroyHash(hHash);
- hHash = NULL;
- }
- if(hKeyProv != NULL && bFreeKeyProv)
- {
- CryptReleaseContext(hKeyProv, 0);
- hKeyProv = NULL;
- }
- if(hCert != NULL)
- {
- CertFreeCertificateContext(hCert);
- hCert = NULL;
- }
- if(hCertStore != NULL)
- {
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- hCertStore = NULL;
- }
- return S_OK;
- }
- //验证签名(无证书验证)
- STDMETHODIMP CSignedData::VerifySign(BSTR Signed_base64, BSTR Cert_base64, BSTR orgData, BOOL* verifySuc)
- {
- // TODO: Add your implementation code here
- // 准备数据
- BYTE* signedData;
- string cstrSigned = _bstr_t (Signed_base64);
- string decodeData = base64_decode(cstrSigned);
- int len = decodeData.size();
- signedData = new BYTE[len] ;
- for(int i = 0; i < len; ++i)
- {
- signedData[i] = (byte)decodeData[i];
- }
- signedData[len] = '\0';
- // 请求容器服务
- HCRYPTPROV hProv = NULL;
- if(!CryptAcquireContext(
- &hProv, // 返回的句柄
- NULL, // CSP key 容器名称
- TEST_CSP_NAME, // CSP 提供者名称
- PROV_RSA_FULL, // CSP 提供者类型
- 0)) // 附加参数
- {
- return E_FAIL;
- }
- // 创建离散对象
- HCRYPTHASH hHash = NULL;
- if(!CryptCreateHash(
- hProv, // 容器句柄
- CALG_MD5, // 算法标识
- NULL, // 算法使用的Key
- 0, // 算法标识
- &hHash)) // 返回的HASH对象
- {
- CryptReleaseContext(hProv, 0);
- return E_FAIL;
- }
- string cstrOrgData = _bstr_t (orgData);
- BYTE* orgBlob;
- int orglen = cstrOrgData.size();
- orgBlob = new BYTE[orglen] ;
- for(int i = 0; i < orglen; ++i)
- {
- orgBlob[i] = (byte)cstrOrgData[i];
- }
- orgBlob[orglen] = '\0';
- // 计算数据摘要
- if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)
- {
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- return E_FAIL;
- }
- // 获取签名者证书公钥
- /*
- HCERTSTORE WINAPI CertOpenStore(
- __in LPCSTR lpszStoreProvider,
- __in DWORD dwMsgAndCertEncodingType,
- __in HCRYPTPROV_LEGACY hCryptProv,
- __in DWORD dwFlags,
- __in const void* pvPara
- );
- */
- BYTE* cert;
- string cstrCert_base64 = _bstr_t (Cert_base64);
- string decodeCert = base64_decode(cstrCert_base64);
- int certLen = decodeCert.size();
- cert = new BYTE[certLen] ;
- for(int i = 0; i < certLen; ++i)
- {
- cert[i] = (byte)decodeCert[i];
- }
- cert[certLen] = '\0';
- PCCERT_CONTEXT pCertContext = NULL;
- if(pCertContext = CertCreateCertificateContext(
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // The encoding type
- cert, // The encoded data from
- // the certificate retrieved
- certLen)) // The length of the encoded data
- {
- printf("A new certificate has been created.\n");
- // Use the certificate context as needed.
- // ...
- }
- else
- {
- printf("A new certificate could not be created.\n");
- return E_FAIL;
- }
- HCRYPTKEY hPubKey;
- if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
- {
- CryptDestroyKey(hPubKey);
- CryptReleaseContext(hProv, 0);
- return E_FAIL;
- }
- // 校验签名
- /*
- BOOL WINAPI CryptVerifySignature(
- __in HCRYPTHASH hHash,
- __in BYTE* pbSignature,
- __in DWORD dwSigLen,
- __in HCRYPTKEY hPubKey,
- __in LPCTSTR sDescription,
- __in DWORD dwFlags
- );
- */
- if(!CryptVerifySignature(hHash, signedData, len, hPubKey, NULL, 0))
- {
- *verifySuc=false;
- return S_FALSE;
- }
- else
- {
- *verifySuc=true;
- }
- // 释放获取的对象
- if(hPubKey != NULL)
- {
- CryptDestroyKey(hPubKey);
- hPubKey = NULL;
- }
- if(hHash != NULL)
- {
- CryptDestroyHash(hHash);
- hHash = NULL;
- }
- if(pCertContext != NULL)
- {
- CertFreeCertificateContext(pCertContext);
- pCertContext = NULL;
- }
- if(hProv != NULL)
- {
- CryptReleaseContext(hProv, 0);
- hProv = NULL;
- }
- return S_OK;
- }
- //带证书验证部分的签名验证
- STDMETHODIMP CSignedData::VerifySignWithCRL(BSTR Signed_base64, BSTR Cert_base64, BSTR orgData, BSTR CRL_base64, BOOL* verifySuc)
- {
- // TODO: 在此添加实现代码
- // TODO: Add your implementation code here
- // 准备数据
- BYTE* signedData;
- string cstrSigned = _bstr_t (Signed_base64);
- string cstrCRL_base64 = _bstr_t(CRL_base64);
- int count = cstrCRL_base64.size();
- string decodeData = base64_decode(cstrSigned);
- int len = decodeData.size();
- signedData = new BYTE[len] ;
- for(int i = 0; i < len; ++i)
- {
- signedData[i] = (byte)decodeData[i];
- }
- signedData[len] = '\0';
- // 请求容器服务
- HCRYPTPROV hProv = NULL;
- if(!CryptAcquireContext(
- &hProv, // 返回的句柄
- NULL, // CSP key 容器名称
- TEST_CSP_NAME, // CSP 提供者名称
- PROV_RSA_FULL, // CSP 提供者类型
- 0)) // 附加参数
- {
- return E_FAIL;
- }
- // 创建离散对象
- HCRYPTHASH hHash = NULL;
- if(!CryptCreateHash(
- hProv, // 容器句柄
- CALG_MD5, // 算法标识
- NULL, // 算法使用的Key
- 0, // 算法标识
- &hHash)) // 返回的HASH对象
- {
- CryptReleaseContext(hProv, 0);
- return E_FAIL;
- }
- string cstrOrgData = _bstr_t (orgData);
- BYTE* orgBlob;
- int orglen = cstrOrgData.size();
- orgBlob = new BYTE[orglen] ;
- for(int i = 0; i < orglen; ++i)
- {
- orgBlob[i] = (byte)cstrOrgData[i];
- }
- orgBlob[orglen] = '\0';
- // 计算数据摘要
- if(CryptHashData(hHash, orgBlob, orglen, 0) == 0)
- {
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
- return E_FAIL;
- }
- // 获取签名者证书公钥
- /*
- HCERTSTORE WINAPI CertOpenStore(
- __in LPCSTR lpszStoreProvider,
- __in DWORD dwMsgAndCertEncodingType,
- __in HCRYPTPROV_LEGACY hCryptProv,
- __in DWORD dwFlags,
- __in const void* pvPara
- );
- */
- BYTE* cert;
- string cstrCert_base64 = _bstr_t (Cert_base64);
- string decodeCert = base64_decode(cstrCert_base64);
- int certLen = decodeCert.size();
- cert = new BYTE[certLen] ;
- for(int i = 0; i < certLen; ++i)
- {
- cert[i] = (byte)decodeCert[i];
- }
- cert[certLen] = '\0';
- PCCERT_CONTEXT pCertContext = NULL;
- if(pCertContext = CertCreateCertificateContext(
- X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, // The encoding type
- cert, // The encoded data from
- // the certificate retrieved
- certLen)) // The length of the encoded data
- {
- printf("A new certificate has been created.\n");
- // Use the certificate context as needed.
- // ...
- }
- else
- {
- printf("A new certificate could not be created.\n");
- return E_FAIL;
- }
- bool certIsValid = verifyCert(pCertContext,cstrCRL_base64);
- if(certIsValid){
- HCRYPTKEY hPubKey;
- if(!CryptImportPublicKeyInfo(hProv, pCertContext->dwCertEncodingType, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey))
- {
- CryptDestroyKey(hPubKey);
- CryptReleaseContext(hProv, 0);
- return E_FAIL;
- }
- // 校验签名
- /*
- BOOL WINAPI CryptVerifySignature(
- __in HCRYPTHASH hHash,
- __in BYTE* pbSignature,
- __in DWORD dwSigLen,
- __in HCRYPTKEY hPubKey,
- __in LPCTSTR sDescription,
- __in DWORD dwFlags
- );
- */
- if(!CryptVerifySignature(hHash, signedData, len, hPubKey, NULL, 0))
- {
- *verifySuc=false;
- return S_FALSE;
- }
- else
- {
- *verifySuc=true;
- }
- if(hPubKey != NULL)
- {
- CryptDestroyKey(hPubKey);
- hPubKey = NULL;
- }
- }else{
- *verifySuc=false;
- }
- // 释放获取的对象
- if(hHash != NULL)
- {
- CryptDestroyHash(hHash);
- hHash = NULL;
- }
- if(pCertContext != NULL)
- {
- CertFreeCertificateContext(pCertContext);
- pCertContext = NULL;
- }
- if(hProv != NULL)
- {
- CryptReleaseContext(hProv, 0);
- hProv = NULL;
- }
- return S_OK;
- }
- // 校验证书合法性
- bool verifyCert(PCCERT_CONTEXT hCert,string CRL_base64)
- {
- /*
- *获取CRLContext对象
- */
- string CRL = base64_decode(CRL_base64);
- BYTE *pbCRL = NULL;
- pbCRL = new BYTE[CRL.size()];
- for(int i=0;i<CRL.size();i++){
- pbCRL[i]=(BYTE)CRL[i];
- }
- int cbCRL = CRL.size();
- pbCRL[cbCRL]='\0';
- PCCRL_CONTEXT hCRL = CertCreateCRLContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pbCRL,cbCRL);
- if(hCRL==NULL){
- printf("未找到CRL");
- }else{
- printf("找到CRL");
- }
- /**//*
- LONG WINAPI CertVerifyTimeValidity(
- __in LPFILETIME pTimeToVerify,
- __in PCERT_INFO pCertInfo
- );
- */
- // 校验证书日期
- int nRetCode = CertVerifyTimeValidity(NULL, hCert->pCertInfo);
- if(nRetCode < 0)
- {
- printf("Verify cert's date failed: BEFORE date after TODAY!\n");
- return false;
- }
- if(nRetCode > 0)
- {
- printf("Verify cert's date failed: Cert has expired!\n");
- return false;
- }
- if(nRetCode == 0)
- {
- printf("Verify cert's date succeed!\n");
- }
- // 校验签名者证书
- HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"ROOT");
- if(hCertStore != NULL)
- {
- /**//*
- PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(
- __in HCERTSTORE hCertStore,
- __in PCCERT_CONTEXT pSubjectContext,
- __in_opt PCCERT_CONTEXT pPrevIssuerContext,
- __in_out DWORD* pdwFlags
- );
- */
- // 2.
- DWORD dwFlags = CERT_STORE_SIGNATURE_FLAG;
- PCCERT_CONTEXT hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, NULL, &dwFlags);
- if(hIssuserCert != NULL)
- {
- BOOL bCheckOK = FALSE;
- while(hIssuserCert != NULL)
- {
- /**//*
- BOOL WINAPI CertVerifySubjectCertificateContext(
- __in PCCERT_CONTEXT pSubject,
- __in_opt PCCERT_CONTEXT pIssuer,
- __in_out DWORD* pdwFlags
- );
- */
- // 校验证书签发者信息合法性
- dwFlags = CERT_STORE_SIGNATURE_FLAG;
- if(CertVerifySubjectCertificateContext(hCert, hIssuserCert, &dwFlags))
- {
- if(dwFlags == 0)
- {
- printf("Verify cert by issuser's cert succeed! \n");
- bCheckOK = TRUE;
- break;
- }
- }
- else
- {
- printf("Verify cert by issuser's cert failed! \n");
- return false;
- break;
- }
- // Next ..
- hIssuserCert = CertGetIssuerCertificateFromStore(hCertStore, hCert, hIssuserCert, &dwFlags);
- }
- if(!bCheckOK)
- {
- printf("Verify cert by issuser's cert failed! \n");
- return false;
- }
- }
- else
- {
- printf("Can not find cert issuser's cert!\n");
- }
- if(hIssuserCert != NULL)
- {
- CertFreeCertificateContext(hIssuserCert);
- hIssuserCert = NULL;
- }
- }
- else
- {
- printf("Open ROOT CertStore failed!\n");
- return false;
- }
- if(hCertStore != NULL)
- {
- CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
- hCertStore = NULL;
- }
- // 校验 CRL 列表
- // 1.
- //BYTE* pbCrlData = NULL;
- //DWORD cbCrlData = 0;
- //readFile("c:\\cfcaT.crl", NULL, cbCrlData);
- //if(cbCrlData > 0)
- //{
- // pbCrlData = (BYTE*) new char[cbCrlData];
- // readFile("c:\\cfcaT.crl", pbCrlData, cbCrlData);
- //}
- ///**//*
- // PCCRL_CONTEXT WINAPI CertCreateCRLContext(
- // __in DWORD dwCertEncodingType,
- // __in const BYTE* pbCrlEncoded,
- // __in DWORD cbCrlEncoded
- // );
- // */
- 2.转换CRL数据为CRL句柄
- //PCCRL_CONTEXT hCRL = CertCreateCRLContext(MY_ENCODING_TYPE, pbCrlData, cbCrlData);
- //delete [] pbCrlData;
- if(hCRL != NULL)
- {
- /**//*
- BOOL WINAPI CertIsValidCRLForCertificate(
- __in PCCERT_CONTEXT pCert,
- __in PCCRL_CONTEXT pCRL,
- __in DWORD dwFlags,
- __in void* pvReserved
- */
- if(CertIsValidCRLForCertificate(hCert, hCRL, 0, NULL))
- {
- printf("CRL is valid for the cert!\n");
- }
- else
- {
- printf("CRL is invalid for the cert!!\n");
- return false;
- }
- /**//*
- BOOL WINAPI CertFindCertificateInCRL(
- __in PCCERT_CONTEXT pCert,
- __in PCCRL_CONTEXT pCrlContext,
- __in DWORD dwFlags,
- __in_opt void* pvReserved,
- __out PCRL_ENTRY* pCrlEntry
- );
- */
- // Step 4: 检查CRL是否包含该证书
- PCRL_ENTRY pCrlEntry = NULL;
- if(CertFindCertificateInCRL(hCert, hCRL, 0, 0, &pCrlEntry))
- {
- if(pCrlEntry != NULL)
- {
- printf("Cert has been revoked!\n");
- return false;
- }
- else
- {
- printf("Cert not be revoked!\n");
- }
- }
- else
- {
- printf("Find cert in CRL failed!\n");
- return false;
- }
- }
- else
- {
- printf("Create CRL context failed!\n");
- return false;
- }
- if(hCRL != NULL)
- {
- CertFreeCRLContext(hCRL);
- }
- } </span>
编写ATL工程实现ActiveX控件调用cryptoAPI接口(一)------------签名与验证相关推荐
- 编写ATL工程实现ActiveX控件调用cryptoAPI接口(三)------------AES对称加密与解密
注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出. [cpp] view plain copy print ? /* * * * 文件名称:Enc ...
- 编写ATL工程实现ActiveX控件调用cryptoAPI接口(二)------------信封加密与解密
注:下面的代码中用了Map,Base64,log,Result等都为自定义类型,太长就不一一贴出. [cpp] view plain copy print ? /* * * * 文件名称:Env ...
- 使用ATL创建简单ActiveX控件(一) —— 创建ATL项目
创建过程以VS2010为例,分三篇(创建ATL项目.添加方法/属性和枚举.添加连接点)演示.本篇演示创建ATL项目. 传送门: <使用ATL创建简单ActiveX控件(二) -- 添加方法/属性 ...
- 如何在VB中实现ActiveX控件的IobjectSafety接口
如何在VB中实现ActiveX控件的IobjectSafety接口 ------------------------------------------------------------------ ...
- 关于vlc播放器的ActiveX控件调用问题
下了好几个版本的vlc播放器,却发现vlc播放器自带的ActiveX插件除了初始化能用之外,后面的js接口完全用不了 从1.0.5版本之后的ActiveX无法调用第一版的js接口 从2.0.5版本之后 ...
- 开发ActiveX控件调用另一个ActiveX系列0——身份证识别仪驱动的问题
程序员要从0下表开始,这篇是介绍这个系列的背景的,没有兴趣的人可以直接跳过. 为什么要开发ActiveX控件 由于工作需要,我们开发了一个网站,使用了一款身份证识别仪的网页ActiveX(OCX)插件 ...
- ie浏览器java 脚本下载_如何设置ie浏览器中的activex控件和插件java脚本下载用户验证...
ActiveX是Microsoft提出的一组使用COM(ComponentObjectModel,部件对象模型)使得软件部件在网络环境中进行交互的技术集.它与具体的编程语言无关.作为针对Interne ...
- VS创建ATL项目,ActiveX控件
1. 前言 最近一直在做浏览器控件相关,面向IE浏览器.虽然IE有各种缺点,但是还是有很多项目是基于IE的.呃呃呃,比如需要与硬件交互,可以需要多个控件配合,最起码我遇到了(签名控件VCTK和一些远程 ...
- [转]ASP中ActiveX控件的内嵌及调用
懂ASP(Active Server Pages)的人很多,但能用ASP自如地调用ActiveX控件的人却不多:如果不调用ActiveX控件,则可以说微软当初设计ASP的初衷根本没有达到.众所周知,A ...
最新文章
- Jenkins分布式部署配置
- python整数类型在每一台计算机上的取值范围是一样的_第四章、Python数据类型
- hdu 5606(并查集)
- python调用可执行文件
- vue监听路由的变化,跳转到同一个页面时,Url改变但视图未重新加载问题
- linux验证db2安装成功_DB2(Linux 64位)安装教程
- PCB板设计流程有哪些?
- resin设置权限_resin加固
- 20182319彭淼迪 2019-2020-1 《数据结构与面向对象程序设计》实验一报告
- 【源码】林业害虫检测小程序(可拓展美化)
- 应用交付能给客户带来什么价值?
- Python简单GUI(模拟放大镜)
- TCP三次握手原理详解
- mac定时执行python_Mac中的定时任务利器:launchctl
- Linux企业级服务之实现DNS子域服务器
- 告别盗版杀软!免费用17款鼎鼎大名的杀毒软件
- IOS 通过麦克风检测声音分贝
- 书单 | 本本经典,学算法就从这里选了!
- 为什么打印机显示服务器脱机,为什么打印机显示服务器脱机
- 视频教程-【吴刚】技术答疑与项目讲评视频教程(随时更新)-UI
热门文章
- Docker+NETCore系列文章(三、Docker常用命令)
- Altium Designer 20 如何快速给不规则板框铺铜的方法,超级简单操作!
- 欧科云链接受北京电视台采访:以创新科技助力《反电信网络诈骗法》实施
- 如何实现html5页面,自动提示添加到主屏幕
- 单片机中c语言 右移 和左移 与CY
- html格式字体颜色入门(颜色表格查询)
- 商业研究(9):入口思维(刚需、频次、免费、变现)
- arch linux u盘安装,从U盘安装archlinux-2009.08完整过程 - Leo's Utopia
- 【Lua进阶系列】lua元方法
- python脚本无缝拼接图片