⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mwtools.cpp

📁 RSA算法的VC源码
💻 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 + -