// Rsa.cpp: implementation of the CRsa class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Signature.h"
#include "Window.h"
#include "Rsa.h"
#include "GfL.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////////
CRsa::CRsa()
{
Zero = BI.New(0);
key = n = Zero;
}
///////////////////////////////////////////////////////////////////////////////
// CRsa Functions
///////////////////////////////////////////////////////////////////////////////
#define CHECK(x) {if( !(x) ) return false;}
#define CHECK_MSG(x,msg) {if( !(x) ){CWindow::ShowMessage(msg); {CloseFile(); return 0;}}}
/******************************************************************************/
/******************************************************************************/
// 名称:Encrypt
// 功能:加密
// 参数:len为加密内容的长度;KeyStr,ModStr为0结尾的密钥串,用于设置RSA密钥和模n
// 返回:加密(解密)后的密文(明文)长度
// 备注:
// 更新:2003/1/25
// 作者:0200950原常青
/******************************************************************************/
bool CRsa::Encrypt(char *OutFile,char *InFile,char *RsaKeyStr,char *RsaModStr)
{
CHECK( RsaKeyStr && RsaModStr && OpenFile(OutFile,InFile) )
CWindow wnd;
wnd.ShowWaitCursor();
wnd.SetWindowCaption("RSA正在加密......");
long FileLen;
int l = 0;
static BigInt a,c;
McsHead mcshead;
char buf[128];
SIG = "";
strr = "";
memset (buf,'\0',sizeof(buf));
if(!(OutFile && InFile && SetKey(RsaKeyStr,RsaModStr)))
{
CloseFile();
return false;
}
int rsamodlength = 0;
rsamodlength = strlen(RsaModStr);
FileLen = n.len/2 - 1; //用于加密的明文长度一定要小于模的长度
FILE* ff;
ff=fopen(InFile,"rb");
if(!ff)
{
AfxMessageBox("打开文件错误");
return 0;
}
CString bf = "signature:\r\n";
_lwrite(fh_out, bf.GetBuffer(0), strlen(bf));
char bufstrr[128];
char bufstrr1[256];
memset(bufstrr, 0, 128);
memset(bufstrr1, 0, 256);
char buflength[4] = {"\0"};
CString strhex;
CString strlength;
while(fread (buf, 1, FileLen, ff))
{
memset (mcshead.buffer,'\0',sizeof(mcshead.buffer));
strhex = "";
strlength = "";
// 由输入构造一个大数a
BI.BuildBIFromByte(a,buf,FileLen);
// 加密(解密)
BI.PowMod(c,a,key,n);
CGfL::HalfByteToByte(mcshead.buffer,c.bit,c.len);
mcshead.mlen = ((c.len+1)>>1);
SIG += mcshead.buffer;
// _lwrite(fh_out, (char*)&mcshead, sizeof(mcshead));
l = l+sizeof(mcshead);
memset (buf,'\0',sizeof(buf));
if(rsamodlength <= 128)
{
char temp[3];
for (int i=0; i<(int)n.len/2; i++)
{
sprintf(temp, "%02x", (unsigned char)mcshead.buffer[i]);
strhex += temp;
strr += temp;
}
char tempp[3];
sprintf(tempp, "%02x", mcshead.mlen);
strlength = tempp;
sprintf(bufstrr, "%s", strhex.GetBuffer(0));
_lwrite(fh_out, bufstrr, sizeof(bufstrr));
sprintf(buflength, "%s", strlength.GetBuffer(0));
_lwrite(fh_out, buflength, sizeof(buflength));
}
else
{
char temp[3];
for (int i=0; i<(int)n.len/2; i++)
{
sprintf(temp, "%02x", (unsigned char)mcshead.buffer[i]);
strhex += temp;
strr += temp;
}
if(strhex.GetLength() > 128)
{
char tempp[3];
sprintf(tempp, "%02x", mcshead.mlen);
strlength = tempp;
sprintf(bufstrr1, "%s", strhex.GetBuffer(0));
_lwrite(fh_out, bufstrr1, sizeof(bufstrr1));
sprintf(buflength, "%s", strlength.GetBuffer(0));
_lwrite(fh_out, buflength, sizeof(buflength));
}
}
}
char *str = new char[3];
sprintf(str, "%d", l);
CString ss = "\r\n--length:";
ss = ss + str + "--\r\n";
_lwrite(fh_out, ss.GetBuffer(0), strlen(ss));
fclose(ff);
wnd.EndWaitCursor();
CloseFile();
delete str;
return true;
}
bool CRsa::Decrypt(char *InFile,char *RsaKeyStr,char *RsaModStr)
{
CHECK( RsaKeyStr && RsaModStr && OpenFiletemp(InFile) )
CWindow wnd;
wnd.ShowWaitCursor();
wnd.SetWindowCaption("RSA正在解密......");
static BigInt a,c;
SIG = "";
McsHead mcshead;
if(!(InFile && SetKey(RsaKeyStr,RsaModStr)))
{
CloseFile();
return false;
}
while(_lread(fh_in,&mcshead,sizeof(mcshead)))
{
// 由输入构造一个大数a
BI.BuildBIFromByte(a,mcshead.buffer,n.len/2);
// 加密(解密)
BI.PowMod(c,a,key,n);
memset (mcshead.buffer,'\0',sizeof(mcshead.buffer));
CGfL::HalfByteToByte(mcshead.buffer,c.bit,c.len);
SIG += mcshead.buffer;
memset (mcshead.buffer,'\0',sizeof(mcshead.buffer));
if(n.len > 64)
{
break;
}
}
wnd.EndWaitCursor();
CloseFile();
return true;
}
////////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
// 名称:SetKey
// 功能:由输入密钥串设置RSA密钥和模n
// 参数:KeyStr,ModStr为0结尾的密钥串,对应密钥和模n
// 返回:设置成功返回true,否则返回false
// 备注:
// 更新:2003/1/25
// 作者:0200950原常青
/******************************************************************************/
bool CRsa::SetKey(char *KeyStr,char *ModStr)
{
int klen,nlen;
key = n = Zero;
CHECK_MSG( KeyStr && ModStr && KeyStr && (klen=strlen(KeyStr)) && (nlen=strlen(ModStr)) &&
klen<=nlen && BI.BuildBIFromStr(key,KeyStr,klen) && BI.BuildBIFromStr(n,ModStr,nlen),
"设置RSA密钥出错:空密钥,或密钥太长!" )
return true;
}
/******************************************************************************/
// 名称:GetKey
// 功能:获取RSA密钥对
// 参数:
// 返回:获取成功返回true,否则返回false
// 备注:如果p,q非空,请保证其为素数。如果需要产生素数p,q,请在调用前将p,q置0
// 更新:2003/1/25
// 作者:0200950原常青
/******************************************************************************/
bool CRsa::GetKey(BigInt &p,BigInt &q,BigInt &e,BigInt &d,BigInt &n,
UINT plen,UINT qlen,UINT elen)
{
BigInt p_1,q_1,n_1,tmp;
// 如果p,q=0,则产生素数
if( !p.len )
CHECK( BI.GetPrime(p,plen) )
if( !q.len )
CHECK( BI.GetPrime(q,qlen) )
CHECK_MSG( p.len>4 && p.len<=BI_MAXLEN/4 && q.len>4 && q.len<=BI_MAXLEN/4 &&
elen>=max(p.len,q.len) && elen<=p.len+q.len, "长度不在合法范围之内! " )
CHECK_MSG( BI.Cmp(p,q), "错误:素数p,q相同! " )
// 计算n
CHECK( BI.Mul(n,p,q) )
// 防止密钥长度超过N,以免造成死循环
if( elen>n.len )
elen = n.len;
p_1 = p; p_1.bit[0] -= 1;
q_1 = q; q_1.bit[0] -= 1;
CHECK( BI.Mul(n_1,p_1,q_1) )
while( true )
{
BI.RandVal(e,elen);
if( BI.Cmp(e,n)<0 && BI.Inverse(e,d,n_1,tmp) )
return true;
}
}
///////////////////////////////////////////////////////////////////////////////
// End of Files
///////////////////////////////////////////////////////////////////////////////