diff options
| -rw-r--r-- | envelope.cpp | 88 | ||||
| -rw-r--r-- | envelope.h | 13 | ||||
| -rw-r--r-- | main.cpp | 16 | 
3 files changed, 115 insertions, 2 deletions
diff --git a/envelope.cpp b/envelope.cpp new file mode 100644 index 0000000..a8cd793 --- /dev/null +++ b/envelope.cpp @@ -0,0 +1,88 @@ +#include <cassert> +#include "aes.h" +#include "base64.h" //TODO: remove +#include "envelope.h" +#include "rng.h" + +using namespace std; + +namespace Envelope{ + +	bool safeKey(const string &key){ +		//checks against keys 0 and 1, because they don't undergo change in RSA +		int i; +		for(i=0;i<(int)key.size();i++)if(key[i]!=0)break; +		if(i==(int)key.size())return false; //key is 0 +		if(i==(int)key.size()-1&&key[i]==1)return false; //key is 1 +		return true; //fine +	} + +	string encrypt(const string &data,const RSA::PublicKey &pubkey){ +		const int keylen=8; //256-bit +		CryptoRng crng; +		string key(4*keylen,'\0'); +		do { +			for(int i=0;i<keylen;i++)*(uint32_t*)&key[4*i]=crng.get(); +		} while(!safeKey(key)); +		//cerr<<"WARNING: using predetermined envelope key"<<endl; +		//key="kaasKAASkaasKAAShalloHALLOhallo!"; + +		cerr<<"decrkey="<<Base64::encode(key)<<endl; +		 +		string payload(AES::encrypt(data,key,AES::AES_256_CBC)); +		cerr<<"payload="<<Base64::encode(payload)<<endl; +		Bigint rsadata; +		for(int i=0;i<(int)key.size();i++){ +			if(i!=0)rsadata<<=8; +			rsadata+=(uint8_t)key[i]; +		} +		cerr<<"rsadata="<<rsadata<<endl; +		// cerr<<"We encrypt:"<<endl<<"  "<<rsadata<<endl; +		Bigint res(RSA::encrypt(rsadata,pubkey)); +		// cerr<<"to:"<<endl<<"  "<<res<<endl; +		vector<uint8_t> bytes; //bytes in little-endian order +		while(res!=0){ +			bytes.push_back(res.lowdigits()&0xff); +			res>>=8; +		} +		cerr<<"encrkey="<<Base64::encode(string(bytes.rbegin(),bytes.rend()))<<endl; +		payload.reserve(payload.size()+bytes.size()+2); +		for(int i=bytes.size()-1;i>=0;i--)payload.push_back(bytes[i]); +		payload.push_back(bytes.size()>>8); +		payload.push_back((uint8_t)bytes.size()&0xff); + +		return payload; +	} + +	string decrypt(const string &data,const RSA::PrivateKey &privkey){ +		cerr<<"=== DECRYPT ==="<<endl; +		if(data.size()<2)throw invalid_argument("Envelope data length invalid"); +		int encrkeylen=((uint16_t)data[data.size()-2]<<8)+(uint16_t)data.back(); +		assert(encrkeylen<(1<<16)); +		cerr<<"encrkeylen="<<encrkeylen<<endl; +		if((int)data.size()<encrkeylen+2)throw invalid_argument("Envelope key format invalid"); +		string encrkey(encrkeylen,'\0'); +		for(int i=0;i<encrkeylen;i++){ +			encrkey[i]=data[data.size()-2-encrkeylen+i]; +		} +		cerr<<"encrkey="<<Base64::encode(encrkey)<<endl; +		Bigint rsadata; +		for(int i=0;i<encrkeylen;i++){ +			if(i!=0)rsadata<<=8; +			rsadata+=(uint8_t)encrkey[i]; +		} +		Bigint res(RSA::decrypt(rsadata,privkey)); +		cerr<<"rsadata="<<res<<endl; +		vector<uint8_t> bytes; //bytes in little-endian order +		while(res!=0){ +			bytes.push_back(res.lowdigits()&0xff); +			res>>=8; +		} +		string decrkey(bytes.size(),'\0'); +		for(int i=0;i<(int)bytes.size();i++)decrkey[bytes.size()-1-i]=bytes[i]; +		cerr<<"decrkey="<<Base64::encode(decrkey)<<endl; +		cerr<<"payload="<<Base64::encode(data.substr(0,data.size()-2-encrkeylen))<<endl; +		return AES::decrypt(data.substr(0,data.size()-2-encrkeylen),decrkey,AES::AES_256_CBC); +	} + +} diff --git a/envelope.h b/envelope.h new file mode 100644 index 0000000..a72a7ad --- /dev/null +++ b/envelope.h @@ -0,0 +1,13 @@ +#pragma once + +#include <string> +#include "rsa.h" + +namespace Envelope{ + +	std::string encrypt(const std::string &data,const RSA::PublicKey &pubkey); + +	//throws invalid_argument for an invalid ciphertext (length invalid) +	std::string decrypt(const std::string &data,const RSA::PrivateKey &privkey); + +} @@ -10,6 +10,7 @@  #include "aes.h"  #include "base64.h"  #include "bigint.h" +#include "envelope.h"  #include "numalgo.h"  #include "primes.h"  #include "rng.h" @@ -223,6 +224,17 @@ int main(int argc,char **argv){  	// cout<<Base64::decode(s)<<flush;*/  	// AES::test(); -	cout<<Base64::encode(AES::encrypt("123456789abcdefx","goeiemorgen dit is leuke data enzoo",AES::AES_128_CBC))<<endl; -	cout<<AES::decrypt("123456789abcdefx",Base64::decode("dv2N3n2FHsD7LU2PAZnZm/bLQQSaaZoDDFjy3VrSu2JCHN5KuyBlinlh9C71IGTbT4/WvRKLp6dp1TfrKXIG2w=="),AES::AES_128_CBC)<<endl; +	// cout<<Base64::encode(AES::encrypt("goeiemorgen dit is leuke data enzoo","123456789abcdefx",AES::AES_128_CBC))<<endl; +	// cout<<AES::decrypt(Base64::decode("dv2N3n2FHsD7LU2PAZnZm/bLQQSaaZoDDFjy3VrSu2JCHN5KuyBlinlh9C71IGTbT4/WvRKLp6dp1TfrKXIG2w=="),"123456789abcdefx",AES::AES_128_CBC)<<endl; + +	RSA::PrivateKey privkey(RSA::genkey(2048,"goeiemorgen")); +	cerr<<"privkey.pexp="<<privkey.pexp<<endl; +	// stringstream ss("146142527763115590918816237475833862275078269531224490080731579415134484175830244922030574137988310092068583287060550616357026989772917226684940867892409"); +	// Bigint d; +	// ss>>d; +	// cout<<RSA::decrypt(d,privkey)<<endl; +	string crypt(Envelope::encrypt("hallo hallo dit is leuke data enzo",privkey.pub)); +	cout<<Base64::encode(crypt)<<endl; +	string decr(Envelope::decrypt(crypt,privkey)); +	cout<<decr<<endl;  }  | 
