📄 mwtools.cpp
字号:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "Windows.h"
#include "mpilib.h"
#include "rsagen.h"
#include "genprime.h"
//#include "sys/times.h"
#include "time.h"
#include "sys/types.h"
unsigned char strBuffer[2048];
unsigned short m_C[MAX_UNIT_PRECISION];
unsigned short m_CC[MAX_UNIT_PRECISION];
unsigned short m_CCC[MAX_UNIT_PRECISION];
unsigned short m_P[MAX_UNIT_PRECISION];
unsigned short m_Q[MAX_UNIT_PRECISION];
unsigned short m_N[MAX_UNIT_PRECISION];
unsigned short m_E[MAX_UNIT_PRECISION];
unsigned short m_D[MAX_UNIT_PRECISION];
unsigned short m_U[MAX_UNIT_PRECISION];
unsigned short m_QU[MAX_UNIT_PRECISION];
unsigned short temp[MAX_UNIT_PRECISION];
unsigned short m_DP[MAX_UNIT_PRECISION];
unsigned short m_DQ[MAX_UNIT_PRECISION];
unsigned char InputChar[2048];
extern void SHA(unsigned char *pbData, unsigned long dwDataLen, unsigned char *pDigest);
extern int WINAPI Hash(int len,unsigned char* InBuf,unsigned char* OutBuf);
extern int WINAPI GenRsaKey(unsigned char *PK,unsigned char *SK);
extern int WINAPI MkSign(int len,unsigned char *Msg,unsigned char *SK,unsigned char *Sign);
extern int WINAPI VerifySign(int Len,unsigned char *Msg,unsigned char *PK,unsigned char *VerifyData);
extern int WINAPI asc_hex(unsigned char *asc, unsigned char *hex, int pair_len);
extern int WINAPI hex_asc(unsigned char *hex,unsigned char *asc,int length);
extern int WINAPI asc_asc(unsigned char *src,unsigned char *des,long len);
extern int WINAPI asc_hex(unsigned char *asc, unsigned char *hex, int pair_len)
{
char src1,src2;
int len;
for (len=0; len < pair_len; len++)
{
src1 = *(asc+len*2);
src2 = *(asc+len*2+1);
if ((src1>='0') && (src1<='9'))
src1=src1-'0';
else if ((src1>='A') && (src1<='F'))
src1=src1-'A'+10;
else if ((src1>='a') && (src1<='f'))
src1=src1-'a'+10;
else
return -1;
if ((src2>='0') && (src2<='9'))
src2=src2-'0';
else if ((src2>='A') && (src2<='F'))
src2=src2-'A'+10;
else if ((src2>='a') && (src2<='f'))
src2=src2-'a'+10;
else
return -1;
*hex++ = (src1 << 4) | src2;
}
return 0;
}
extern int WINAPI hex_asc(unsigned char *hex,unsigned char *asc,int length)
{
unsigned char hLowbit,hHighbit;
int i;
for(i=0;i<length*2;i=i+2)
{
hLowbit=hex[i/2]&0x0f;
hHighbit=hex[i/2]/16;
if(hHighbit>=10)
asc[i]=hHighbit+'7';
else
asc[i]=hHighbit+'0';
if(hLowbit>=10)
asc[i+1]=hLowbit+'7';
else
asc[i+1]=hLowbit+'0';
}
asc[length*2]='\0';
return 0;
}
extern int WINAPI asc_asc(unsigned char *src,unsigned char *des,long len)
{
memcpy(des,src,len);
return 0;
}
void Short2Char(unsigned char *OutMsg,int InLen,unsigned short *InShort)
{
int i,j;
unsigned char tmp[2];
for(i=0;i<InLen;i++)
{
j=InLen-1-i;
memcpy(tmp,InShort+i,2);
/*高,低位作置换*/
OutMsg[2*j]=tmp[1];
OutMsg[2*j+1]=tmp[0];
}
}
void Char2Short(unsigned short *OutShort,int InLen,unsigned char *InMsg)
{
int i,j;
unsigned char tmp[2];
for(i=0;i<InLen;i++)
{
j=InLen-1-i;
/*高,低位作置换*/
tmp[0]=InMsg[2*i+1];
tmp[1]=InMsg[2*i];
memcpy(OutShort+j,tmp,2);
}
}
/**************************************************
摘要算法
输入参数: len 数据长度
InBuf 要摘要的数据包
OutBuf 摘要的结果
返回: 0 正确
<0 错误
***************************************************/
int WINAPI Hash(int len,unsigned char* InBuf,unsigned char* OutBuf)
{
SHA(InBuf,len,OutBuf);
return 0;
}
/*
void GetRandomN(unsigned char *RandomN,int nn)
{
int i;
for(i=0;i<nn;i++)
RandomN[i]=rand()%256;
}
*/
void ShortToChar(unsigned char*des,unsigned short*src,int len)
{
char ch;
for(int i=0;i<len;i++)
{
int j=len-1-i;
ch=src[i]&0x000f;
if(ch<=9 && ch>=0)
des[j*4+3]=ch+0x30;
else
des[j*4+3]=ch+0x61-10;
ch=(src[i]&0x00f0)>>4;
if(ch<=9 && ch>=0)
des[j*4+2]=ch+0x30;
else
des[j*4+2]=ch+0x61-10;
ch=(src[i]&0x0f00)>>8;
if(ch<=9 && ch>=0)
des[j*4+1]=ch+0x30;
else
des[j*4+1]=ch+0x61-10;
ch=(src[i]&0xf000)>>12;
if(ch<=9 && ch>=0)
des[j*4]=ch+0x30;
else
des[j*4]=ch+0x61-10;
}
//des[len*2]='\0';//这句话值得考虑
}
/**************************************************
生成RSA算法的密钥对(1024BIT)
输入参数:
PK 公钥, N + E , 132字节。
SK 私钥, Q + P + Qinv + DQ + DP,320字节。
返回:0 正确
<0 错误
***************************************************/
int WINAPI GenRsaKey(unsigned char *uPK,unsigned char *uSK)
{
srand( (unsigned)time( NULL ) );
char PK[1024];
char SK[1024];
unitptr p,q,n,e,d,u,qu;
unsigned int nn;
short nbits, bits;
nn = 0x400;
nbits=nn/2;
bits=nbits/16; /* 60 is the largest!!! */
global_precision = 2*bits;
p=m_P;q=m_Q;n=m_N;e=m_E;d=m_D;qu=m_QU;u=m_U;
int i = randomprime( p, nbits);
i = randomprime( q, nbits);
if (mp_compare(p,q) >= 0) { /* ensure that p<q
for computing u */
mp_move(u,p);
mp_move(p,q);
mp_move(q,u);
}
derive_rsakeys(n,e,d,p,q,qu,5);
unsigned char temp1[1024];
ShortToChar(temp1,n,2*bits);
temp1[8*bits]='\0';
strcpy(PK,"");
wsprintf(PK,"%s%s",PK,temp1);
ShortToChar(temp1,e,2);
temp1[8]='\0';
wsprintf(PK,"%s%s",PK,temp1);
asc_hex((unsigned char*)PK,uPK,strlen(PK)/2);
ShortToChar(temp1,q,bits);
temp1[4*bits]='\0';
strcpy(SK,(const char*)temp1);
ShortToChar(temp1,p,bits);
temp1[4*bits]='\0';
wsprintf(SK,"%s%s",SK,temp1);
ShortToChar(temp1,qu,bits);
temp1[4*bits]='\0';
wsprintf(SK,"%s%s",SK,temp1);
mp_move(temp,m_P);
mp_dec(temp);
mp_mod(m_DP,m_D,temp);
mp_move(temp,m_Q);
mp_dec(temp);
mp_mod(m_DQ,m_D,temp);
ShortToChar(temp1,m_DP,bits);
temp1[4*bits]='\0';
wsprintf(SK,"%s%s",SK,temp1);
ShortToChar(temp1,m_DQ,bits);
temp1[4*bits]='\0';
wsprintf(SK,"%s%s",SK,temp1);
asc_hex((unsigned char*)SK,uSK,strlen(SK)/2);
/********************顺序处理 zhp*********************
uSK顺序: (Q,P,Qinv,DP,DQ)
改为卡顺序: (Q,P,Qinv,DQ,DP)
*******************************************************/
unsigned char uCharData[1024];
memset(uCharData,0x00,sizeof(uCharData));
memcpy(uCharData,uSK,192);
//DQ
memcpy(&uCharData[192],&uSK[256],64);
//DP
memcpy(&uCharData[256],&uSK[192],64);
memcpy(uSK,uCharData,320);
/*******************************************************/
for (i = 0; i <2*bits-1; i++) m_C[i]=65000+i+1;
m_C[2*bits-1]=0;
i = mp_modexp(m_CC,m_C,e,n);
//i = mp_modexp_crt(m_CCC, m_CC, m_P, m_Q, m_DP, m_DQ, m_QU);
i = mp_modexp(m_CCC,m_CC,d,n);
for (i = 0; i <2*bits; i++)
if (m_CCC[i] !=m_C[i]) break;
if (i<bits)
{
return -1;
}
return 0;
}
/*********************************************************
计算签名
输入参数: len 数据长度,当len>128时,对Msg的摘要签名,当len<=128
时,对Msg签名。
Msg 要签名的数据包
Sk 签名密钥 (柜员私钥)
输出参数: Sign 签名, 128字节
***********************************************************/
int WINAPI MkSign(int Len,unsigned char *Msg,unsigned char *SK,unsigned char *SignData)
{
unsigned char Buf[2048];
int ret;
if(Len<0)
return -1;
global_precision=64;
memset(strBuffer,0,2048);
memset(Buf,0,2048);
memset(m_CC,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_CCC,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_P,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_Q,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_DP,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_DQ,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_U,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
if(Len>128)
{
/*计算摘要*/
return -1;
}
else
{
memcpy(&Buf[128-Len],Msg,Len);
Len=128;
Char2Short(&m_CC[0],Len/2,Buf);
}
memcpy(Buf,SK,64);
Char2Short(m_Q,32,Buf);
memcpy(Buf,SK+64,64);
Char2Short(m_P,32,Buf);
memcpy(Buf,SK+128,64);
Char2Short(m_U,32,Buf);
memcpy(Buf,SK+192,64);
//change by Joyce Peng
Char2Short(m_DQ,32,Buf);
//Char2Short(m_DP,32,Buf);
memcpy(Buf,SK+256,64);
Char2Short(m_DP,32,Buf);
//Char2Short(m_DQ,32,Buf);
ret=mp_modexp_crt(m_CCC, m_CC, m_P, m_Q, m_DP, m_DQ, m_U);
if(ret!=0)
return -1;
Short2Char(SignData,64,m_CCC);
return 0;
}
/*************************************************************************************
签名校验
输入参数:
len 数据(Msg)长度
Msg 要校验的数据包(Msg=Data + Sign最后128字节为签名)。当Data的长度大于128时,
Sign解密后与Data的摘要比较,相同为签名正确;当Data的长度<=128时,Sign解密
后与Data比较,相同为签名正确
Pk 签名校验密钥 (柜员公钥),132 字节。
返回: 0 签名正确
<0 签名错误
****************************************************************************************/
int WINAPI VerifySign(int Len,unsigned char *Msg,unsigned char *PK,unsigned char *VerifyData)
{
unsigned char Buf[2048],Tmp[2048];
int ret;
if(Len<0)
return -1;
global_precision=64;
memset(strBuffer,0,2048);
memset(Buf,0,2048);
memset(Tmp,0,2048);
memset(m_C,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_E,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_N,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_CC,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
if(Len>128)
{
return -1;
}
else
{
memset(Tmp,0,128);
memcpy(&Buf[128-Len],Msg,Len);
}
Char2Short(m_C,64,Buf);
Char2Short(m_N,64,PK);
Char2Short(m_E,2,PK+128);
ret=mp_modexp(m_CC,m_C,m_E,m_N);
if(ret!=0)
return -1;
Short2Char(VerifyData,64,m_CC);
return 0;
}
/* 后台函数(As/400)
void VerifySign(int Len,unsigned char *Msg,unsigned char *PK int *OK)
{
unsigned char Buf[2048],Tmp[2048];
int ret,DataLen;
if(Len<128)
{
*OK=-1;
return;
}
global_precision=64;
memset(strBuffer,0,2048);
memset(Buf,0,2048);
memset(Tmp,0,2048);
memset(m_C,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_E,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_N,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
memset(m_CC,0,MAX_UNIT_PRECISION*sizeof(unsigned short));
if(Len>256)
{
memcpy(Buf,Msg,Len-128);
Hash(Len-128,Buf,Tmp);
memset(Buf,0,128);
memcpy(&Buf[128-20],Tmp,20);
memcpy(Tmp,Buf,128);
}
else
{
memset(Tmp,0,128);
memcpy(&Tmp[256-Len],Msg,Len-128);
}
memcpy(Buf,Msg+Len-128,128);
Char2Short(m_C,64,Buf);
Char2Short(m_N,64,PK);
Char2Short(m_E,2,PK+128);
ret=mp_modexp(m_CC,m_C,m_E,m_N);
if(ret!=0)
{
*OK=-1;
return;
}
Short2Char(Buf,64,m_CC);
if(memcmp(Buf,Tmp,128)!=0)
{
*OK=-1;
return;
}
*OK=0;
}
*/
/*
void main()
{
unsigned char strBuff[2000],strResult[2000];
unsigned char PK[500],SK[500];
long i;
unsigned char tmp[1024],buf[1024];
memcpy(tmp,"12345678",8);
asc_hex(tmp,buf,4);
for(i=0;i<1;i++)
memcpy(strBuff+i*4,buf,4);
memcpy(tmp,"da7948bb03ed1bbb5270593f23fd236b4d7e0d5f707b26e974f26af80c77347f69f961ff04df327b1c5e32fe50ee1eba7b6f19f52df42a12716f507b3c5626bff8150dbd4b7d64e661e75eef746f1e4f26ff49f57f7313e74ffe032e67d56ffb327468f12d7f2f7953d95ee65efb6533114703ff617f546b215f30ef22665a53c80401f235c5fe7da11bfa9933f9ad53afbe97bfa8db16e4e58c8b224d475568d13cdfdafa3add9c987c25736fe4917d69446e1f69d30031a268a6e62c77334146f6e6ce3e58e95309b080b4a8aedc91b1cb1721f5ca3a6851b68cbc6a91608e0fb9c30732878e51fb8d539b3c9257398b78b0090e9fb8cb48698d7aea7132e7282847b5a8e1113f7240710ccae31a8e3bc108066d39101f8a4caef514cc30530e9f1c1392cfeaa6a5cc5b54b85206dc6dbe58ddb5c68e41b06e32664cb8d19a",640);
asc_hex(tmp,SK,320);
i=MkSign(4,strBuff,SK,strResult);
if(i!=0)
{
printf("ERR");
return;
}
memcpy(&strBuff[4],strResult,128);
memcpy(tmp,"d3b77621d7cdc238f915c6a1008a45ef13a4a6d4fd9c3aaebc6b92b9857411e8b212f01d1000c0588006c1e91c5ed52f88b80283739b8830f74977d581272e24a56c07141cebdef8bdd925657f34229fc99331e8335e75428f76319fbebd3ad57888ac59904e4ca6b18591e062ea6bbdc16b03ab8e5db60fd412e2f4a7a7b5ed00010001",264);
asc_hex(tmp,PK,132);
i=VerifySign(132,strBuff,PK,strResult);
if(i!=0)
{
printf("ERR1");
return;
}
for(i=0;i<128;i++)
{
if(!(i%64))
printf("\n");
printf("%02x",strResult[i]);
}
return ;
memset(strBuff,0x34,50);
SHA(strBuff,4,strResult);
GenRsaKey(PK,SK);
memcpy(tmp,"12345678",8);
asc_hex(tmp,buf,4);
for(i=0;i<2;i++)
memcpy(strBuff+i*4,buf,4);
i=MkSign(8,strBuff,SK,strResult);
if(i!=0)
{
printf("ERR");
return;
}
memcpy(&strBuff[4],strResult,128);
memset(strBuff,0,128);
i=VerifySign(128,strResult,PK);
if(i!=0)
{
printf("ERR1");
return;
}
for(i=0;i<128;i++)
{
if(!(i%64))
printf("\n");
printf("%02x",strBuff[i]);
}
return;
printf("PK(N E): \n");
for(i=0;i<132;i++)
{
if(!((i)%128))
printf("\n");
printf("%02x",PK[i]);
}
printf("\n\n");
printf("SK(P Q DP DQ U): \n");
for(i=0;i<320;i++)
{
if(!(i%64))
printf("\n");
printf("%02x",SK[i]);
}
}*/
/*
Q: da7948bb03ed1bbb5270593f23fd236b4d7e0d5f707b26e974f26af80c77347f69f961ff04df327b1c5e32fe50ee1eba7b6f19f52df42a12716f507b3c5626bf
P: f8150dbd4b7d64e661e75eef746f1e4f26ff49f57f7313e74ffe032e67d56ffb327468f12d7f2f7953d95ee65efb6533114703ff617f546b215f30ef22665a53
Qinv:c80401f235c5fe7da11bfa9933f9ad53afbe97bfa8db16e4e58c8b224d475568d13cdfdafa3add9c987c25736fe4917d69446e1f69d30031a268a6e62c773341
DQ: 46f6e6ce3e58e95309b080b4a8aedc91b1cb1721f5ca3a6851b68cbc6a91608e0fb9c30732878e51fb8d539b3c9257398b78b0090e9fb8cb48698d7aea7132e7
DP: 282847b5a8e1113f7240710ccae31a8e3bc108066d39101f8a4caef514cc30530e9f1c1392cfeaa6a5cc5b54b85206dc6dbe58ddb5c68e41b06e32664cb8d19a
N: d3b77621d7cdc238f915c6a1008a45ef13a4a6d4fd9c3aaebc6b92b9857411e8b212f01d1000c0588006c1e91c5ed52f88b80283739b8830f74977d581272e24a56c07141cebdef8bdd925657f34229fc99331e8335e75428f76319fbebd3ad57888ac59904e4ca6b18591e062ea6bbdc16b03ab8e5db60fd412e2f4a7a7b5ed
E: 00010001
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -