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

📄 rsawapper.cpp

📁 RSA 1024位加密算法封装
💻 CPP
字号:
#include "stdafx.h"
#include "RSAWapper.h"
#include "RSACrypt.h"
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <assert.h>

using namespace std;
#define SHOWERROR wprintf
class RSAImpl
{
public:
	RSAImpl(const int keyLen):keyLen_(keyLen)
	{if(keyLen!=1024) throw std::length_error("Only support 1024bit length.");}

	~RSAImpl(){}

	typedef big::u1024 PubKeySizeT;
	
	void generateKeys(){myKeys_.generateKeys();}
	void reset(){myKeys_.reset();}
	BIGSMALLTYPE void setPrivateKey( Smaller &c_p, Smaller &c_q ){myKeys_.setPrivateKey(c_p,c_q);}
	BIGSMALLTYPE void getPrivateKey( Smaller &c_p, Smaller &c_q ){myKeys_.getPrivateKey(c_p,c_q);}
	void setPublicKey( u32 c_e, PubKeySizeT &c_n ){myKeys_.setPublicKey(c_e,c_n);}
	void getPublicKey( u32 &c_e, PubKeySizeT &c_n ){myKeys_.getPublicKey(c_e,c_n);}
	void encrypt( PubKeySizeT &M, PubKeySizeT &x ){myKeys_.encrypt(M,x);}
	void decrypt( PubKeySizeT &M, PubKeySizeT &x ){myKeys_.decrypt(M,x);}
	int GetPubKeyLen() const {return keyLen_;}

	BIGONETYPE static void BufToNum(T & pNum,const BYTE* inbuf,const size_t inLen)
	{
		//Byte-order swapping.(u32) and byte-order swap (the big::u512 struct)
		assert(inLen<=sizeof(pNum));
		if((BYTE*)pNum!=inbuf){
			assert((BYTE*)pNum-inbuf-inLen>=0||inbuf-(BYTE*)pNum-sizeof(pNum)>=0);
			memset(pNum,0,sizeof(pNum));
			memcpy(pNum,inbuf,inLen);
		}
		u32 temp;
		const int pNumElementCount=sizeof(pNum)/sizeof(pNum[0]);
		assert(sizeof(pNum[0])==sizeof(u32));
		for(int i=0;i<pNumElementCount/2;++i){
			temp=BOSWAP32(pNum[i]);
			pNum[i]=BOSWAP32(pNum[pNumElementCount-1-i]);
			pNum[pNumElementCount-1-i]=temp;
		}
	}

	BIGONETYPE static void NumToBuf(T & pNum,BYTE* outBuf,const size_t outBufLen)
	{
		BYTE* pOut=outBuf;
		if(outBufLen<sizeof(T)) pOut=new BYTE[sizeof(T)];
		new(pOut) T;	//placement new. Now (because T here must be big::uXXX, and it is a int array, which has no ctor) it is nouse.
		memcpy(pOut,pNum,sizeof(T));
		BufToNum(*((T*)outBuf),outBuf,sizeof(T));
		if(pOut!=outBuf){
			memcpy(outBuf,pOut,outBufLen);
			delete[] pOut;
		}
	}

private:
	const int keyLen_;
	big::RSACrypt<big::u1024> myKeys_;
};



RSAWapper::RSAWapper(const int RSAPubKeyLength_InBit):myKeys(new RSAImpl(RSAPubKeyLength_InBit))
{
	if(RSAPubKeyLength_InBit!=1024) throw std::length_error("Only support 1024bit length.");
}

RSAWapper::~RSAWapper(void)
{
}

void RSAWapper::GenerateKeys()
{
	myKeys->generateKeys();
}

void RSAWapper::setPriKeys(const BYTE* pBuf,const size_t pBufLen,const BYTE* qBuf,const size_t qBufLen)
{
	BIGHALFSIZE(RSAImpl::PubKeySizeT, p);
	BIGHALFSIZE(RSAImpl::PubKeySizeT, q);
	RSAImpl::BufToNum(p,pBuf,pBufLen);
	RSAImpl::BufToNum(q,qBuf,qBufLen);
	myKeys->setPrivateKey(p,q);
}

void RSAWapper::setPubKeys(const int e,const BYTE* nBuf,const size_t nBufLen)
{
	big::u32 e_=e;
	RSAImpl::PubKeySizeT n;
	RSAImpl::BufToNum(n,nBuf,nBufLen);
	myKeys->setPublicKey(e,n);
}

void RSAWapper::getPubKeys(int& e,BYTE* nBuf,const size_t nBufLen) const
{
	big::u32 e_;
	RSAImpl::PubKeySizeT n;
	myKeys->getPublicKey(e_,n);
	e=e_;
	RSAImpl::NumToBuf(n,nBuf,nBufLen);
}

void RSAWapper::getPriKeys(BYTE* pBuf,const size_t pBufLen,BYTE* qBuf,const size_t qBufLen) const
{
	BIGHALFSIZE(RSAImpl::PubKeySizeT, p);
	BIGHALFSIZE(RSAImpl::PubKeySizeT, q);
	myKeys->getPrivateKey(p,q);
	RSAImpl::NumToBuf(p,pBuf,pBufLen);
	RSAImpl::NumToBuf(q,qBuf,qBufLen);
}

bool RSAWapper::LoadKeys(const std::string& keyFileName, bool LoadPriKeyAlso)
{
	std::basic_ifstream<big::word> pubKey1((keyFileName+".Pub").c_str(),ifstream::binary);
	big::u32 e;
	RSAImpl::PubKeySizeT n;
	if(pubKey1.is_open()){
		pubKey1.read(&e,sizeof(e)/sizeof(u32));
		pubKey1.read(n,sizeof(n)/sizeof(u32));
		if(pubKey1.fail()) throw("Read Pub key error");
	}
	else return false;
	pubKey1.close();
	myKeys->setPublicKey(e,n);
	if(LoadPriKeyAlso){
		std::basic_ifstream<big::word> priKey1((keyFileName+".Pri").c_str(),ifstream::binary);
		BIGHALFSIZE(RSAImpl::PubKeySizeT, p);
		BIGHALFSIZE(RSAImpl::PubKeySizeT, q);
		if(priKey1.is_open()){
			priKey1.read(p,sizeof(p)/sizeof(u32));
			priKey1.read(q,sizeof(q)/sizeof(u32));
			if(priKey1.fail()) throw("Read Pri key error");
			priKey1.close();
		}
		else return false;
		myKeys->setPrivateKey(p,q);
	}
	return true;
}

void RSAWapper::SaveKeys(const std::string& keyFileName,bool SavePriKeyAlso) const
{
	big::u32 e;
	RSAImpl::PubKeySizeT n;
	myKeys->getPublicKey(e,n);
	std::basic_ofstream<big::word> PubK((keyFileName+".Pub").c_str(),ifstream::binary);
	PubK.write(&e,sizeof(e)/sizeof(u32));
	PubK.write(n,sizeof(n)/sizeof(u32));
	if(PubK.fail()) SHOWERROR(L"Save PubKey to file error.\n");
	PubK.close();
	if(SavePriKeyAlso){
		BIGHALFSIZE(RSAImpl::PubKeySizeT, p);
		BIGHALFSIZE(RSAImpl::PubKeySizeT, q);
		myKeys->getPrivateKey(p,q);
		std::basic_ofstream<big::word> PriK((keyFileName+".Pri").c_str(),ifstream::binary);
		PriK.write(p,sizeof(p)/sizeof(u32));
		PriK.write(q,sizeof(q)/sizeof(u32));
		if(PriK.fail()) SHOWERROR(L"Save PriKey to file error.\n");
		PriK.close();
	}
}


void RSAWapper::Encrypt(const BYTE* inBuf,const size_t inLen,BYTE* outBuf,const size_t outBufLen) const
{
	if(inLen>sizeof(RSAImpl::PubKeySizeT)-2) throw std::length_error("input for Enc is too long!");
	RSAImpl::PubKeySizeT inNum,encNum;
	memset(inNum,0,sizeof(inNum));
	memcpy((BYTE*)inNum+2,inBuf,inLen);
	RSAImpl::BufToNum(inNum,(BYTE*)&inNum[0],sizeof(inNum));
	myKeys->encrypt(inNum,encNum);
	RSAImpl::NumToBuf(encNum,outBuf,outBufLen);
}


size_t RSAWapper::Decrypt(const BYTE* inBuf,BYTE* outBuf,const size_t outBufLen) const
{
	RSAImpl::PubKeySizeT encNum,plainNum;
	RSAImpl::BufToNum(encNum,inBuf,sizeof(encNum));
	myKeys->decrypt(encNum,plainNum);
	BYTE* pOut=(BYTE*)plainNum;
	RSAImpl::NumToBuf(plainNum,pOut,sizeof(plainNum));
	size_t outLen;
	if(*(++pOut)==1){
		//Do nothing.
	}
	else if(*pOut==0){
		//Do nothing.
	}
	else{
		//Unknow.
		SHOWERROR(L"Unkown padding:%d while Decrypt.\n",*pOut);
	}
	outLen=sizeof(plainNum)-(++pOut-(BYTE*)plainNum);
	outLen=(outLen>outBufLen)?outBufLen:outLen;
	memcpy(outBuf,pOut,outLen);
	return outLen;
}

void RSAWapper::Sign(const BYTE* inBuf,const size_t inLen,BYTE* outBuf,const size_t outBufLen) const
{
	RSAImpl::PubKeySizeT inNum,signedNum;
	if(inLen<=sizeof(inNum)-11){
		//PKCS 1.5 padding
		memset(inNum,0,sizeof(inNum));
		BYTE* p=(BYTE*)inNum;
		*(++p)=1;
		const int Pad_FF_Len=sizeof(inNum)-inLen-3;
		memset(++p,0xff,Pad_FF_Len);
		p+=Pad_FF_Len;
		*p=0;
		memcpy(++p,inBuf,inLen);
		assert(p+inLen-(BYTE*)inNum==sizeof(inNum));
	}
	else if(inLen<=sizeof(inNum)-2){
		//00 padding
		memset(inNum,0,sizeof(inNum));
		memcpy((BYTE*)inNum+2,inBuf,inLen);
	}
	else throw std::length_error("input for sign is too long!");
	RSAImpl::BufToNum(inNum,(BYTE*)&inNum[0],sizeof(inNum));
	myKeys->decrypt(inNum,signedNum);
	RSAImpl::NumToBuf(signedNum,outBuf,outBufLen);
}

size_t RSAWapper::Authen(const BYTE* inBuf,BYTE* outBuf,const size_t outBufLen) const
{
	RSAImpl::PubKeySizeT signNum,plainNum;
	RSAImpl::BufToNum(signNum,inBuf,sizeof(signNum));
	myKeys->encrypt(signNum,plainNum);
	BYTE* pOut=(BYTE*)plainNum;
	RSAImpl::NumToBuf(plainNum,pOut,sizeof(plainNum));
	size_t outLen;
	if(*(++pOut)==1){
		//PKCS 1.5 padding.
		while(*(++pOut)==0xff);
		
	}
	else if(*pOut==0){
		//Maybe 00 padding.
		//Do nothing.
	}
	else{
		//Unknow.
		SHOWERROR(L"Unkown padding:%d while unsign.\n",*pOut);
	}
	outLen=sizeof(plainNum)-(++pOut-(BYTE*)plainNum);
	outLen=(outLen>outBufLen)?outBufLen:outLen;
	memcpy(outBuf,pOut,outLen);
	return outLen;
}

#ifdef _ARM_

bool RSAWapper::LoadKeysforMobile(const std::string& keyFileName)
{
	std::basic_ifstream<BYTE> AllKey((keyFileName+".key").c_str(),ifstream::binary);
	if(AllKey.is_open()){
		AllKey.read((BYTE*)&*myKeys,sizeof(RSAImpl));
		if(AllKey.fail()) throw("Read error");
	}
	else return false;
	AllKey.close();
	return true;
}

void RSAWapper::SaveKeysforMobile(const std::string& keyFileName)
{
	std::basic_ofstream<BYTE> AllK((keyFileName+".key").c_str(),ifstream::binary);
	AllK.write((BYTE*)&*myKeys,sizeof(RSAImpl));
	if(AllK.fail()) SHOWERROR(L"Save AllKeys to file error.\n");
	AllK.close();
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -