CryptoAPI:用数字证书加密数据

来源:互联网 发布:java定义错误枚举类 编辑:程序博客网 时间:2024/04/30 05:41
因为公司最近要做一个读取市民卡信息的项目,从读卡器中读取到用户姓名和身份证后要用数字签名进行加密,然后再进行传输,在网上找了很久,终于找到相关的资料,稍微修改后在visual studio 2010中添加为一个类,在此记下,以供以后忘记时能用上。
//////////头文件/////////#pragma once#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x0501#endif #pragma comment (lib, "crypt32.lib")#include <stdio.h>#include <malloc.h>#include <windows.h>#include <wincrypt.h>#define MY_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)class EncryptByCert{public:EncryptByCert(void);~EncryptByCert(void);//变量声明public:HCERTSTORE hStoreHandle;//系统证书库BYTE* pbMessage;//预签名消息DWORD cbMessage;//预签名消息长度PCCERT_CONTEXT pSignerCert;//签名证书CRYPT_SIGN_MESSAGE_PARA SigParams;//签名参数结构DWORD cbSignedMessageBlob;//签名数据块长度BYTE *pbSignedMessageBlob;//签名数据块DWORD cbDecodedMessageBlob;//解码数据块长度BYTE *pbDecodedMessageBlob;//解码数据块CRYPT_VERIFY_MESSAGE_PARA VerifyParams;        //验证参数结构//成员函数声明public:CString PadLeft(CString strSrc,int iLen,const char src);CString Hex2Str_OnetoTwo(BYTE byteSrc[],int byteLen);void Str2Hex_TwotoOne(CString strSrc,BYTE byteDist[],int byteLen);BOOL OpenCertStore(CString strStoreName);BOOL GetSignerCert(CString strSignerName);int SignMessage(BYTE *bIn, BYTE *bOut, DWORD inlen, DWORD &outlen);int EncryptSignMsg(CString strSrc, CString &strDes);int UnSignMessage(BYTE *bIn, BYTE *bOut, DWORD inlen);int DecryptSignMsg(CString strSrc, CString &strDes);BOOL Release();};
//////////源文件/////////#include "stdafx.h"#include "EncryptByCert.h"EncryptByCert::EncryptByCert(void){//初始化变量hStoreHandle = NULL;pbMessage = NULL;pbSignedMessageBlob = NULL;pbDecodedMessageBlob = NULL;}EncryptByCert::~EncryptByCert(void){}CString EncryptByCert::PadLeft(CString strSrc,int iLen,const char src){CString strDist;int strlen = strSrc.GetLength();if (iLen <= strlen){strDist = strSrc.Left(iLen);return strDist;}for (int i = 0;i < iLen - strlen;i++){strDist += src;}strDist.Append(strSrc);return strDist;}CString EncryptByCert::Hex2Str_OnetoTwo(BYTE byteSrc[],int byteLen){CString strOut(_T(""));CString strtemp(_T(""));int nTemp = 0;for (int i = 0; i < byteLen; i++){nTemp = byteSrc[i];strtemp.Format(_T("%02x"),nTemp);strOut.Append(strtemp);}return strOut;}void EncryptByCert::Str2Hex_TwotoOne(CString strSrc,BYTE byteDist[],int byteLen){int nmid = 0;CString strmid(_T(""));CString strtemp;if (strSrc.IsEmpty()){return;}if (strSrc.GetLength() < byteLen * 2){//strtemp = strSrc;strtemp = PadLeft(strSrc,byteLen * 2,'0');}elsestrtemp = strSrc;for (int i = 0; i < byteLen; i++){strmid = strtemp.Mid(i * 2,2);nmid = strtol(strmid,NULL,16);byteDist[i] = nmid;}}BOOL EncryptByCert::OpenCertStore(CString strStoreName){BOOL bResult = FALSE;wchar_t wstr[256];MultiByteToWideChar(CP_ACP,0,strStoreName,-1,wstr,256);//打开证书库hStoreHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM,0,NULL,CERT_SYSTEM_STORE_CURRENT_USER,wstr);if(hStoreHandle){bResult = TRUE;}return bResult;}BOOL EncryptByCert::GetSignerCert(CString strSignerName){BOOL bResult = FALSE;wchar_t wstr[256];MultiByteToWideChar(CP_ACP,0,strSignerName,-1,wstr,256);//获取签名证书指针,此证书必须拥有签名私钥pSignerCert = CertFindCertificateInStore(hStoreHandle, MY_TYPE, 0, CERT_FIND_SUBJECT_STR, wstr, NULL);if(pSignerCert){bResult = TRUE;}return bResult;}int EncryptByCert::SignMessage(BYTE *bIn, BYTE *bOut, DWORD inlen, DWORD &outlen){int res = -1;// 创建消息队列及消息长度队列const BYTE* MessageArray[] = {bIn};DWORD MessageSizeArray[1];MessageSizeArray[0] = inlen;//获取签名数据大小if(!CryptSignMessage(&SigParams,//签名参数结构FALSE,//是否拆开1,//消息队列数目MessageArray,//消息队列MessageSizeArray,//消息大小队列NULL,//签名后的数据&cbSignedMessageBlob))//签名数据长度{return res = 1;}outlen = cbSignedMessageBlob;//分配内存pbSignedMessageBlob = new BYTE[cbSignedMessageBlob];//签名操作,pbSignedMessageBlob指向签名数据块if(!CryptSignMessage(&SigParams,//签名参数结构FALSE,//是否拆开1,//消息队列数目MessageArray,//消息队列MessageSizeArray,//消息大小队列pbSignedMessageBlob,//签名后的数据&cbSignedMessageBlob))//签名数据长度{res = 2;}else{memcpy(&bOut[0], pbSignedMessageBlob, cbSignedMessageBlob);res = 0;}return res;}int EncryptByCert::EncryptSignMsg(CString strSrc, CString &strDes){//初始化签名数据结构SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);SigParams.dwMsgEncodingType = MY_TYPE;SigParams.pSigningCert = pSignerCert;SigParams.HashAlgorithm.pszObjId = szOID_RSA_MD5;SigParams.HashAlgorithm.Parameters.cbData = NULL;SigParams.cMsgCert = 1;SigParams.rgpMsgCert = &pSignerCert;SigParams.cAuthAttr = 0;SigParams.dwInnerContentType = 0;SigParams.cMsgCrl = 0;SigParams.cUnauthAttr = 0;SigParams.dwFlags = 0;SigParams.pvHashAuxInfo = NULL;SigParams.rgAuthAttr = NULL;//初始化消息pbMessage = (BYTE*)strSrc.GetBuffer(strSrc.GetLength());strSrc.ReleaseBuffer();cbMessage = strlen((char*) pbMessage) + 1;int res = -1;BYTE out[2048] = {0};DWORD outlen = 0;//开始签名res = SignMessage(pbMessage, out, cbMessage, outlen);if(res == 0){strDes = Hex2Str_OnetoTwo(out, outlen);return res;}else{strDes = _T("");return res;}}int EncryptByCert::UnSignMessage(BYTE *bIn, BYTE *bOut, DWORD inlen){int res = -1;//获取解码消息长度if(!CryptVerifyMessageSignature(&VerifyParams,//验证参数结构0,//签名序号bIn,//签名数据inlen,//签名数据长度NULL,//解码后数据&cbDecodedMessageBlob,//解码后数据长度NULL))//签名证书指针{return res = 1;}//分配内存pbDecodedMessageBlob = new BYTE[cbDecodedMessageBlob];//验证签名,获取解码消息if(!CryptVerifyMessageSignature(&VerifyParams,//验证参数结构0,//签名序号bIn,//签名数据inlen,//签名数据长度pbDecodedMessageBlob,//解码后数据&cbDecodedMessageBlob,//解码后数据长度NULL))//签名证书指针{res = 2;}else{memcpy(&bOut[0], pbDecodedMessageBlob, cbDecodedMessageBlob);res = 0;}return res;}int EncryptByCert::DecryptSignMsg(CString strSrc, CString &strDes){//初始化验证消息结构体VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);VerifyParams.dwMsgAndCertEncodingType = MY_TYPE;VerifyParams.hCryptProv = 0;VerifyParams.pfnGetSignerCertificate = NULL;VerifyParams.pvGetArg = NULL;BYTE in[2048] = {0}, out[2048] = {0};int len = strSrc.GetLength()/2;Str2Hex_TwotoOne(strSrc, in, len);int res = -1;res = UnSignMessage(in, out, len);if(res == 0){//strDes = Hex2Str_OnetoTwo(out, cbMessage);strDes.Format(_T("%s"), out);return res;}else{strDes = _T("");return res;}}BOOL EncryptByCert::Release(){//释放空间、资源if(pbSignedMessageBlob){delete [] pbSignedMessageBlob;pbSignedMessageBlob = NULL;}if(pbDecodedMessageBlob){delete [] pbDecodedMessageBlob;pbDecodedMessageBlob = NULL;}if(pSignerCert)CertFreeCertificateContext(pSignerCert);//关闭证书库if(!CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG)){return FALSE;}return TRUE;}
0 0
原创粉丝点击