Hi,
Problem:
At first I wanted to use a system based on public key
RSA for encrypted files. But i've searched solution for encrypt data
that is larger than FixedMaxPlaintextLength().
I've find to solution on this :
-
http://www.mail-archive.com/crypto...@eskimo.com/msg03084.html
To sum up:
Generate and use a temporary AES key to encrypt the
actual file and use RSA to encrypt the AES key in the firsts octet of
file.
I wrote a class that allows you to do that, I will know what you
think.
PS: I use cryptopp552 in static lib and i compile on VC2005 SP1.
Thanks
------------------------------------------------------------------------------------------------------------------------------
// exemple.cpp
// CARON Hugo
//
y0...@segmentationfault33.net
//
http://segmentationfault33.net
// 04/01/2009
#include "RSAClass.h"
void main(void)
{
const char privFilename[]= "key.priv";
const char pubFilename[] = "key.pub";
const char File[] = "test.mp3";
const char FileCrypt[] = "test.mp3.crypt";
const char FileUncrypt[] = "test-new.mp3";
RSAClass RSACrypt;
//RSACrypt.GenerateRSAKey(2048);
//RSACrypt.SaveKey(pubFilename,privFilename);
RSACrypt.LoadKey(pubFilename,privFilename);
RSACrypt.AES_CTR_Encrypt(File,FileCrypt);
RSACrypt.AES_CTR_Decrypt(FileCrypt,FileUncrypt);
}
-----------------------------------------------------------------------------------------------------------
// RSAClass.h
// CARON Hugo
//
y0...@segmentationfault33.net
//
http://segmentationfault33.net
// 04/01/2009
#pragma once
#include <iostream>
#include <windows.h>
#include <fstream>
#include "cryptopp552/rsa.h"
#include "cryptopp552/modes.h"
#include "cryptopp552/hex.h"
#include "cryptopp552/osrng.h"
#include "cryptopp552/des.h"
#include "cryptopp552/files.h"
#ifdef _DEBUG
# pragma comment ( lib, "cryptlib552d" )
#else
# pragma comment ( lib, "cryptlib552" )
#endif
using namespace std;
class RSAClass
{
public:
RSAClass(void);
~RSAClass(void);
void GenerateRSAKey(unsigned int keyLength);
void LoadKey(const char *pubFilename,const char *privFilename);
void SaveKey(const char *pubFilename,const char *privFilename);
string RSAEncryptString(const char *message);
string RSADecryptString(const char *ciphertext);
void AES_CTR_Encrypt(const char *infile, const char *outfile);
void AES_CTR_Decrypt(const char *infile, const char *outfile);
private:
string privString;
string pubString;
};
-------------------------------------------------------------------------------------------------------------------
// RSAClass.cpp
// CARON Hugo
//
http://segmentationfault33.net
// 04/01/2009
#include "RSAClass.h"
RSAClass::RSAClass(void)
{
}
RSAClass::~RSAClass(void)
{
}
void RSAClass::GenerateRSAKey(unsigned int keyLength)
{
//Random seed
CryptoPP::AutoSeededX917RNG <CryptoPP::DES_EDE3> rng;
//Create private key RSA size keyLength and save in string privKey
CryptoPP::RSAES_OAEP_SHA_Decryptor priv(rng, keyLength);
CryptoPP::HexEncoder privKey(new CryptoPP::StringSink(privString));
priv.DEREncode(privKey);
privKey.MessageEnd();
//Create public key RSA and save in string pubKey
CryptoPP::RSAES_OAEP_SHA_Encryptor pub(priv);
CryptoPP::HexEncoder pubKey(new CryptoPP::StringSink(pubString));
pub.DEREncode(pubKey);
pubKey.MessageEnd();
}
string RSAClass::RSAEncryptString(const char *message)
{
//Load pubString and load encryptor for RSA
CryptoPP::StringSource pubStr(pubString, true, new
CryptoPP::HexDecoder);
CryptoPP::RSAES_OAEP_SHA_Encryptor pub(pubStr);
CryptoPP::AutoSeededX917RNG <CryptoPP::DES_EDE3> rng;
//Crypt the message and return a crypt string
string result;
CryptoPP::StringSource(message, true,
new CryptoPP::PK_EncryptorFilter(rng, pub,
new CryptoPP::HexEncoder(new CryptoPP::StringSink(result))));
return result;
}
string RSAClass::RSADecryptString(const char *ciphertext)
{
CryptoPP::StringSource privStr(privString, true, new
CryptoPP::HexDecoder);
CryptoPP::RSAES_OAEP_SHA_Decryptor priv(privStr);
CryptoPP::AutoSeededX917RNG<CryptoPP::DES_EDE3> rng;
string result;
CryptoPP::StringSource(ciphertext, true,
new CryptoPP::HexDecoder(
new CryptoPP::PK_DecryptorFilter(rng, priv,
new CryptoPP::StringSink(result))));
return result;
}
//Save the pubkey and private key in file
void RSAClass::SaveKey(const char *pubFilename,const char
*privFilename)
{
CryptoPP::StringSource (pubString, true, new CryptoPP::FileSink
(pubFilename));
CryptoPP::StringSource (privString, true, new CryptoPP::FileSink
(privFilename));
}
//Load the pubkey and private key in string
void RSAClass::LoadKey(const char *pubFilename,const char
*privFilename)
{
CryptoPP::FileSource (pubFilename, true, new CryptoPP::StringSink
(pubString));
CryptoPP::FileSource (privFilename, true, new CryptoPP::StringSink
(privString));
}
void RSAClass::AES_CTR_Encrypt(const char *infile, const char
*outfile)
{
try
{
//Open outfile in binary and output
ofstream file( outfile, ios::binary );
BYTE keyAES[ CryptoPP::AES::MAX_KEYLENGTH ];
BYTE ivAES[ CryptoPP::AES::BLOCKSIZE ];
//Generate AES key and iv
CryptoPP::OS_GenerateRandomBlock(false, keyAES,
CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::OS_GenerateRandomBlock(false, ivAES,
CryptoPP::AES::BLOCKSIZE);
//Pass key to string
string AesKey((char*)keyAES, CryptoPP::AES::MAX_KEYLENGTH);
AesKey.append((char*)ivAES, CryptoPP::AES::BLOCKSIZE);
//Crypt string AesKey with RSA and save to file stream in HexFormat
CryptoPP::StringSource pubStr(pubString, true, new
CryptoPP::HexDecoder);
CryptoPP::RSAES_OAEP_SHA_Encryptor pub(pubStr);
CryptoPP::AutoSeededX917RNG <CryptoPP::DES_EDE3> rng;
CryptoPP::StringSource(AesKey, true,
new CryptoPP::PK_EncryptorFilter(rng, pub,
new CryptoPP::HexEncoder(new CryptoPP::FileSink(file))));
//Crypt file with AES-CBC and save to file stream
CryptoPP::AES::Encryption aesEncryption( keyAES,
CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption
( aesEncryption,ivAES );
CryptoPP::FileSource(infile, true,
new CryptoPP::StreamTransformationFilter(cbcEncryption,
new CryptoPP::FileSink(file)));
//Close the stream
file.close();
}
catch(CryptoPP::Exception &e)
{
cout << "CryptoPP::Exception caught: " << e.what() << endl;
}
}
void RSAClass::AES_CTR_Decrypt(const char *infile, const char
*outfile)
{
try
{
//Open infile in binary and read
ifstream file( infile , ios::binary );
BYTE keyAES[ CryptoPP::AES::MAX_KEYLENGTH ];
BYTE ivAES[ CryptoPP::AES::BLOCKSIZE ];
//Read the key in file (size of key crypted by RSA 2048 is 512)
char Key[512];
file.read(Key,512);
//Decrypt Key with RSA private key
CryptoPP::StringSource privStr(privString, true, new
CryptoPP::HexDecoder);
CryptoPP::RSAES_OAEP_SHA_Decryptor priv(privStr);
CryptoPP::AutoSeededX917RNG<CryptoPP::DES_EDE3> rng;
string AesKeyUnCrypt;
CryptoPP::StringSource(Key, true,
new CryptoPP::HexDecoder(
new CryptoPP::PK_DecryptorFilter(rng, priv,
new CryptoPP::StringSink(AesKeyUnCrypt))));
//Copy decrypted key to keyAES and ivAES
memcpy(keyAES,AesKeyUnCrypt.data(),CryptoPP::AES::MAX_KEYLENGTH);
memcpy(ivAES,AesKeyUnCrypt.data()+ CryptoPP::AES::MAX_KEYLENGTH,
CryptoPP::AES::BLOCKSIZE);
//Decrypt file with AES-CBC and save to outfile
CryptoPP::AES::Decryption aesDecryption( keyAES,
CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption
( aesDecryption, ivAES );
CryptoPP::FileSource(file, true,
new CryptoPP::StreamTransformationFilter(cbcDecryption,
new CryptoPP::FileSink(outfile)));
}
catch(CryptoPP::Exception &e)
{
cout << "CryptoPP::Exception caught: " << e.what() << endl;
}
}