📄 cpryto.cpp
字号:
#include "stdafx.h"
#include <stdio.h>
#include <wincrypt.h>
#include "Cpryto.h"
#include "Constant.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
void MyHandleError(char *s);
//==============================================================
//构造函数
CCpryto::CCpryto(void)
{
oriText.length=0;
midText.length=0;
binText.length=0;
}
//==============================================================
//析构函数
CCpryto::~CCpryto(void)
{
//释放CSP
if (CryptReleaseContext(hCryptProvProtel, 0))
{
TRACE("The first call to CryptReleaseContext succeeded. \n");
}
else
{
MyHandleError("Error during CryptReleaseContext! #1 \n");
}
//--------------------------------------------------------------------
// Release the provider handle again.
if (CryptReleaseContext(hCryptProvProtel, 0))
{
TRACE("The second call to CryptReleaseContext succeeded. \n");
}
else
{
MyHandleError("Error during CryptReleaseContext #2 !\n");
}
}
//============================================================
//密钥生成
CString CCpryto::Process2()
{
unsigned int i,j,k;
char buffer[5];
CFile fileKeyBlobPub,fileKeyBlobPri;
CFileException fileException;
CSPCreate(&hCryptProvIWESUN,"IWESUN",NULL);
CSPGenKey(hCryptProvIWESUN,&hPriKeyIWESUN);
CString fbuffer="";
if(CSPExportKey(hPriKeyIWESUN ,PUBLICKEYBLOB,KeyBlobPubIWESUN,&KeyBlobPubIWESUNLen))
{
if(fileKeyBlobPub.Open("C:\\alf\\KeyBlobPub.txt",CFile::modeCreate|CFile::modeWrite,&fileException))
{
i=0;k=0;
while(k<KeyBlobPubIWESUNLen)
{
j=0;
while((j<16)&&(k<KeyBlobPubIWESUNLen))
{
sprintf(buffer,"0x%2X",KeyBlobPubIWESUN[k]);k++;j++;
if(buffer[2]==' ')buffer[2]='0';
buffer[4]=0;
fbuffer+=buffer;
if(j!=16) fbuffer+=",";else fbuffer+="\r\n";
}
}
fileKeyBlobPub.Write(fbuffer,fbuffer.GetLength());
fileKeyBlobPub.Close();
}else
{
//显示错误信息
CString ErrInfo;
ErrInfo.Format("不能打开文件 KeyBlobPub.txt ,error=%u\n",fileException.m_cause);
TRACE(ErrInfo,"错误",MB_OK|MB_ICONERROR);
}
}
fbuffer="";
if(CSPExportKey(hPriKeyIWESUN ,PRIVATEKEYBLOB,KeyBlobPriIWESUN,&KeyBlobPriIWESUNLen))
{
if(fileKeyBlobPri.Open("C:\\alf\\KeyBlobPri.txt",CFile::modeCreate|CFile::modeWrite,&fileException))
{
i=0;k=0;j=0;
while(k<KeyBlobPriIWESUNLen)
{
j=0;
while((j<16)&&(k<KeyBlobPriIWESUNLen))
{
sprintf(buffer,"0x%2X",KeyBlobPriIWESUN[k]);k++;j++;
if(buffer[2]==' ')buffer[2]='0';
buffer[4]=0;
fbuffer+=buffer;
fbuffer+=",";
if(j==16) fbuffer+="\r\n";
}
}
fileKeyBlobPri.Write(fbuffer,fbuffer.GetLength());
fileKeyBlobPri.Close();
}else
{
//显示错误信息
CString ErrInfo;
ErrInfo.Format("不能打开文件 KeyBlobPri.txt ,error=%u\n",fileException.m_cause);
TRACE(ErrInfo,"错误",MB_OK|MB_ICONERROR);
}
}
return CString();
}
//创建alf文件
CString CCpryto::Process3()
{
int i,j;
BYTE KeyBlobPriIWESUN[1172];
DWORD sgLen;
CSPCreate(&hCryptProvIWESUN,NULL,NULL);
sgLen=sizeof(KeyBlobPriIWESUNcon);
if(sgLen!=0)
{
j=0;
for(i=0;i<1172;i++)
{
KeyBlobPriIWESUN[i]=CCpryto::KeyBlobPriIWESUNcon[i]^CCpryto::KeyBlobPubIWESUNcon[j];
j++;if(j>0x100)j=0;
}
CSPImportKey(hCryptProvIWESUN,(BYTE *) KeyBlobPriIWESUN,sgLen,&hPriKeyIWESUN);
}else
{
TRACE("无法加载私密,不能完成数字签名!","错误",MB_OK|MB_ICONERROR);
return NULL ;
}
if(CSPCreateSign(&oriText.buffer[4],oriText.length-4,&oriText.buffer[oriText.length],&sgLen,hCryptProvIWESUN))
{
oriText.length=oriText.length+sgLen;
EnXorCode(oriText.buffer,oriText.length);
midText.length=EnCode(oriText.buffer,midText.buffer,oriText.length);
}
else
{
TRACE("创建数字签名失败!","错误",MB_OK|MB_ICONERROR);
return NULL;
}
midText.buffer[midText.length]=0;
return CString(midText.buffer);
}
CString CCpryto::Process4(CFile *dxpFile)
{
(*dxpFile).Seek(0x2E234C,CFile::begin);
(*dxpFile).Write(KeyBlobPubIWESUNcon,sizeof(KeyBlobPubIWESUNcon));
(*dxpFile).Close();
return CString();
}
//====================================================================
//签名验证
bool CCpryto::Process(bool flag)
{
int i=0,j=0,k=0;
CString text;
bool re;
if(flag)
{
CSPCreate(&hCryptProvProtel,NULL,CRYPT_VERIFYCONTEXT);
if(sizeof(KeyBlobPubIWESUNcon)!=0)
CSPImportKey(hCryptProvProtel,(BYTE *) KeyBlobPubProtel,sizeof(KeyBlobPubProtel),&hPubKeyProtel);
}else
{
CSPCreate(&hCryptProvIWESUN,NULL,CRYPT_VERIFYCONTEXT);
if(sizeof(KeyBlobPubIWESUNcon)!=0)
CSPImportKey(hCryptProvIWESUN,(BYTE *) KeyBlobPubIWESUNcon,sizeof(KeyBlobPubIWESUNcon),&hPubKeyIWESUN);
}
midText.length=DeCode(oriText.buffer,midText.buffer,oriText.length);
EnXorCode(midText.buffer,midText.length);
i=(midText.buffer[3]<<24)|(midText.buffer[2]<<16)|(midText.buffer[1]<<8)|(midText.buffer[0]);
if(i>midText.length) i=midText.length-0x100-2;
if(flag)
{
if(CSPVerifySign(&midText.buffer[4],i, &midText.buffer[4+i],0x100,hCryptProvProtel,hPubKeyProtel))
{
//text="通过PROTEL数字签名认证,协议有效!";
//text+=char(0x0d);
//text+=char(0x0a);
re=true;
}else
{
//text="不能PROTEL通过数字签名认证,协议无效!";
//text+=char(0x0d);
//text+=char(0x0a);
re=false;
}
}else
{
if(CSPVerifySign(&midText.buffer[4],i, &midText.buffer[4+i],0x100,hCryptProvIWESUN,hPubKeyIWESUN))
{
//text="通过IWESUN数字签名认证,协议有效!";
//text+=char(0x0d);
//text+=char(0x0a);
re=true;
}else
{
//text="不能IWESUN通过数字签名认证,协议无效!";
//text+=char(0x0d);
//text+=char(0x0a);
re=false;
}
}
//for(j=0;j<i;j++) text+=(char)midText.buffer[4+j];
return re;
}
//==============================================================
//文本格式化
int CCpryto::EnCode(BYTE *inBuffer,BYTE *outBuffer,int inLen)
{
int i=0,j=0,k=0;
unsigned int x=0,y=0;
if(inLen>0)
{
while((i+3)<=inLen)
{
x=inBuffer[i];x<<=8;
x|=inBuffer[i+1];x<<=8;
x|=inBuffer[i+2];
y=(x>>18)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
y=(x>>12)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
y=(x>>6)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
y=x&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
i=i+3;
}
k=inLen-i;
if(k==1)
{
x=inBuffer[i];
y=(x>>2)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
y=(x<<4)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
outBuffer[j]='=';j++;
outBuffer[j]='=';j++;
}else if (k==2)
{
x=inBuffer[i];x<<=8;
x|=inBuffer[i+1];x<<=8;
y=(x>>18)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
y=(x>>12)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
y=(x>>6)&0x3f;y=listBin2Txt[y];
outBuffer[j]=y;j++;
outBuffer[j]='=';j++;
}
}
outBuffer[j]=0;
return j;
}
//==============================================================
//二进制格式化
int CCpryto::DeCode(BYTE *inBuffer,BYTE *outBuffer, int inLen)
{
int i=0,j=0,k=0;
unsigned int z=0;
BYTE m;
while(i<inLen)
{
z=0;j=0;
while((j<4)&&(i<inLen))
{
m=inBuffer[i];
i++;
m=listTxt2Bin[m];
if(m!=0xff)
{
z=z<<6;
z=z|m;
j++;
}
}
if(j==4)
{
outBuffer[k]=(z>>16)&0xff;
outBuffer[k+1]=(z>>8)&0xff;
outBuffer[k+2]=z&0xff;
k=k+3;
}else if(j==3)
{
outBuffer[k]=(z>>10)&0xff;
outBuffer[k+1]=(z>>2)&0xff;
k=k+2;
}else if(j==2)
{
outBuffer[k]=(z>>4)&0xff;;
k=k+1;
}
else if(j==1)
{
outBuffer[k]=(z)&0xff;
k=k+1;
}
}
return k;
}
//==============================================================
//加扰编解码
bool CCpryto::EnXorCode(BYTE* inBuffer,int len)
{
int i=0,j=0,k=0;
BYTE x=0,y=0,z=0;
k=(inBuffer[3]<<24)|(inBuffer[2]<<16)|(inBuffer[1]<<8)|(inBuffer[0]);
if(k>=len) k=len-0x100-4;
for(i = 0; i < k; i++)
{
x= inBuffer[i+4];
do
{
y=inBuffer[j+k+4];
j++;
if((y==0) ||(j>=0x100))
{
j=0;
}
}while(y==0);
z=(x^y);
inBuffer[i+4]=z;
}
return true;
}
//==============================================================
//获取或创建 Cryptographic Service Provider(CSP)
bool CCpryto::CSPCreate(HCRYPTPROV *hProv,LPCSTR UserName,DWORD Flags)
{
//--------------------------------------------------------------------
//获取一个CSP容器 PROV_RSA_FULL provider.
if(CryptAcquireContext( //Protel产考值
hProv, //0x0012FD04
UserName, //NULL, //0 When dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to NULL
MS_ENHANCED_PROV, //地址501954h "Microsoft Enhanced Cryptographic Provider "
PROV_RSA_FULL, //1
Flags)) //NULL//CRYPT_MACHINE_KEYSET)) //CRYPT_VERIFYCONTEXT //0xF0000000
{
TRACE("获取一个CSP句柄成功。\n");
}else
{
if (GetLastError() == 0x80090016 )
{
TRACE(" 缺省 KeyCSP 不存在。\n");
TRACE(" 创建 KeyCSP。 \n");
}
//创建一个CSP容器
if(CryptAcquireContext(
hProv,
UserName,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
TRACE("创建一个CSP容器成功。\n");
}
else
{
if (GetLastError() == 0x8009000 )
{
TRACE(" CSP容器已经存在。\n");
}
MyHandleError("创建CSP失败。\n");
return false;
}
}
//--------------------------------------------------------------------
// 读取 CSP 名字.
BYTE pbData[1024];
DWORD cbData= 1024;
if(CryptGetProvParam(
*hProv,
PP_NAME,
pbData,
&cbData,
0))
{
TRACE("读取 CSP 名字成功。\n");
TRACE("CSP 名字: %s\n", pbData);
}
else
{
MyHandleError("Error reading CSP name. \n");
return false;
}
//--------------------------------------------------------------------
// 读取 CSP 用户名
if(CryptGetProvParam(
*hProv, // handle to the CSP
PP_CONTAINER, // get the key container name
pbData, // pointer to the key container name
&cbData, // length of name, preset to 100
0))
{
TRACE("CSP 用户名: %s\n",pbData);
}
else
{
// An error occurred while getting the key container name.
MyHandleError("读取 CSP 用户名错误.\n");
//return false;
}
return true;
}
//==============================================================
//加载 CSP 秘钥
bool CCpryto::CSPImportKey(HCRYPTPROV hProv,BYTE *KeyBlob,DWORD dwKeyBlobLen,HCRYPTKEY *phKey)
{
//-----------------------------------------------------------------
//加载 CSP 秘钥
if(CryptImportKey(
hProv,
KeyBlob, //[in] BYTE sequence containing the key CRYPTOAPI_BLOB.
dwKeyBlobLen, //[in] Length, in bytes, of the key BLOB.
0, //If the key BLOB is not encrypted, for example, a PUBLICKEYBLOB, this parameter is not used and must be zero.
0, //Currently used only when a public/private key pair in the form of a PRIVATEKEYBLOB is imported into the CSP.
phKey)) //[out] Pointer to the handle of the imported key. When you have finished using the key,
{
TRACE("加载 CSP 秘钥成功。\n");
}
else
{
TRACE("加载 CSP 秘钥失败。\n");
return false;
}
return true;
}
//==============================================================
//秘钥输出
bool CCpryto::CSPExportKey(HCRYPTKEY hKey ,DWORD BlobType,BYTE *KeyBlob,DWORD *BlobLen)
{
//--------------------------------------------------------------------
if(CryptExportKey(
hKey,
NULL,
BlobType, //PUBLICKEYBLOB or PRIVATEKEYBLOB
0,
KeyBlob,
BlobLen))
{
TRACE("BLOB 长度:%d 。 \n",*BlobLen);
TRACE("秘钥输出成功. \n");
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -