使用Activex主要为了嵌入网页和服务端C#来调用加密。这里只给出关键代码吧
1.私钥解密
STDMETHODIMP CMAddr::DePrivKey(BSTR encode, BSTR* orign) { //HCERTSTORE hCertStore = NULL; BOOL ret=TRUE; HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProv =NULL; BOOL bFreeKeyProv=FALSE; DWORD dwKeyType; HCRYPTKEY hKey = NULL; BYTE* pTempByte=NULL; CString outStr; CString run; run="DecodeJson"; CString b64Str(encode); CString tempStr; CStringDecodeBase64(b64Str,tempStr); Json::Reader reader; Json::Value root; if(NULL==Current_PCTX) { MessageBox("请选择证书!"); goto cleanup; } if (!reader.parse(tempStr.GetBuffer(), root)) { goto cleanup; } DWORD dwCount=root.size(); pTempByte=new BYTE[dwCount]; for(DWORD i=0;i<dwCount;i++) { pTempByte[i]=root[i].asInt(); } run="CryptAcquireCertificatePrivateKey"; ret=CryptAcquireCertificatePrivateKey(Current_PCTX, 0, 0, &hCryptProv, &dwKeyType, &bFreeKeyProv); if(!ret)goto cleanup; run="CryptGetUserKey"; ret=CryptGetUserKey(hCryptProv,AT_KEYEXCHANGE,&hKey); if(!ret)goto cleanup; run="CryptDecrypt"; ret=CryptDecrypt(hKey, 0, true, 0,pTempByte, &dwCount); if(!ret)goto cleanup; for(DWORD i=0;i<dwCount;i++) { outStr.AppendChar(pTempByte[i]); } cleanup: if(NULL!=pTempByte) { delete[] pTempByte; pTempByte=NULL; } if(NULL!=hKey) { CryptDestroyKey(hKey); } if(NULL!=hCryptProv&&bFreeKeyProv) { CryptReleaseContext(hCryptProv,0); } if(!ret) { outStr.Empty(); outStr.Format("ErrorCode:%0x"+run, GetLastError()); } CComBSTR tempSTR(outStr); tempSTR.CopyTo(orign); tempSTR.Empty(); return S_OK; }
STDMETHODIMP CMAddr::EnPubKey(BSTR orign, BSTR cert, BSTR* encode) { PCCERT_CONTEXT pCertContext=NULL; HCERTSTORE hCertStore = NULL; HCRYPTPROV hCryptProv = NULL; HCRYPTKEY hPubKey = NULL; BYTE* pBinByte=NULL; BYTE* pOrignByte=NULL; BOOL ret; DWORD binBytes = 0; CString outStr; CString run; CString tempStr; Json::Value value; //get cert std::wstring scert(cert,SysStringLen(cert)); run="Acquire Context"; ret=CryptAcquireContext(&hCryptProv,NULL, NULL,PROV_RSA_FULL,0); if(!ret)goto cleanup; run="Read Cert"; ret=CryptStringToBinaryW(scert.c_str() , scert.length() ,CRYPT_STRING_BASE64HEADER , NULL , &binBytes ,NULL,NULL); if(!ret)goto cleanup; pBinByte=new BYTE[binBytes]; ZeroMemory(pBinByte,binBytes); ret=CryptStringToBinaryW(scert.c_str() , scert.length() ,CRYPT_STRING_BASE64HEADER , pBinByte, &binBytes ,NULL,NULL); if(!ret)goto cleanup; run="Create Cert"; pCertContext = CertCreateCertificateContext( PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, pBinByte , binBytes ); run="Import PubKey"; ret=CryptImportPublicKeyInfo(hCryptProv,PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &(pCertContext->pCertInfo->SubjectPublicKeyInfo), &hPubKey); if(!ret)goto cleanup; DWORD orignLen=SysStringLen(orign); DWORD pDataLen=orignLen; run="Run Encrypt"; ret=CryptEncrypt(hPubKey,NULL,true,0,NULL,&pDataLen,orignLen); if(!ret)goto cleanup; pOrignByte=new BYTE[pDataLen]; ZeroMemory(pOrignByte,pDataLen); for(DWORD i=0;i<orignLen;i++) { pOrignByte[i]=(BYTE)orign[i]; } ret=CryptEncrypt(hPubKey,NULL,true,0,pOrignByte,&orignLen,pDataLen); if(!ret)goto cleanup; for(DWORD i=0;i<pDataLen;i++) { value[i]=pOrignByte[i]; } tempStr=value.toStyledString().c_str(); CStringEncodeBase64(tempStr,outStr); cleanup: if(NULL!=pOrignByte) { delete[] pOrignByte; pOrignByte=NULL; } if(NULL!=pBinByte) { delete[] pBinByte; pBinByte=NULL; } if(NULL!=pCertContext) { CertFreeCertificateContext(pCertContext); } if(NULL!=hPubKey) { CryptDestroyKey(hPubKey); } if(NULL!=hCryptProv) { CryptReleaseContext(hCryptProv,0); } if(!ret) { outStr.Empty(); outStr.Format(run+"ErrorCode:%0x", GetLastError()); } CComBSTR outStrTemp(outStr); outStrTemp.CopyTo(encode); outStrTemp.Empty(); return S_OK; }
STDMETHODIMP CMAddr::LoadCert(BSTR* certInfo) { //加载会话证书 HCERTSTORE hCertStore = NULL; CString resultStr=""; CString subject = ""; CString sno=""; Json::Value value; CHAR szName[1024]; hCertStore = CertOpenSystemStore( 0, "MY"); if(NULL == hCertStore) { CertCloseStore(hCertStore, 0); MessageBox("CertOpenSystemStore Error!"); goto cleanup; } Current_PCTX = CryptUIDlgSelectCertificateFromStore( hCertStore, NULL,NULL,NULL, CRYPTUI_SELECT_LOCATION_COLUMN,0,NULL); if(!Current_PCTX) { MessageBox("请选择证书!"); goto cleanup; } ZeroMemory(szName,1024); CertNameToStr(Current_PCTX->dwCertEncodingType, &Current_PCTX->pCertInfo->Subject, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, szName, sizeof(szName)); subject.Append(szName); for(DWORD i=0 ;i<Current_PCTX->pCertInfo->SerialNumber.cbData; i++) { BYTE byteTemp =Current_PCTX->pCertInfo->SerialNumber.pbData[i]; byteTemp = (byteTemp&0xF0>>4)|(byteTemp&0x0F<<4); sno.Format("%X"+sno,byteTemp); } value["name"]=Json::Value(sno); value["subject"]=Json::Value(subject); resultStr.Append(value.toStyledString().c_str()); cleanup: CComBSTR tempSTR(resultStr); tempSTR.CopyTo(certInfo); tempSTR.Empty(); if(NULL!=hCertStore) { CertCloseStore(hCertStore,NULL); } return S_OK; } STDMETHODIMP CMAddr::FreeCert(void) { //释放会话证书 if(NULL!=Current_PCTX) { CertFreeCertificateContext(Current_PCTX); Current_PCTX=NULL; } return S_OK; }