📄 rsawapper.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 + -