For the last few days I have been working on this code to develop a class that allow me to crypt a block of byte with many algorithme.
One block will be divided into three equal blocks and every block will be encrypted and decrypted by one of the three algorithme.
I want to discover the main weak points of my code especially concerning cryptography within Crypto++.
It is my first prototype and I'm certain there are many point to discuss in this code.
#include "..\PanawaraReader\common.h"
#include "cryptopp_wrapper.h"
class rServer {
public:
public:
/**
rServer class has for roles :
- Creation of a crypted files.
- Creation of Client Applications.
*/
// MILESTONE 1
/**
Returns a crypted block of 1024 bytes with ECB algorithm.
@param _data input array of 1024 bytes.
@return crypted array of 1024 bytes.
*/
DATA CryptBlockWithAESmodeCBC(char _data[1024]);
/**
Returns a crypted block of 1024 bytes with Blowfish algorithm.
@param _data input array of 1024 bytes.
@return crypted array.
*/
DATA CryptBlockWithBlowfish(char _data[1024]);
/**
Returns a crypted block of 1024 bytes with RSA algorithm.
@param _data input array of 1024 bytes.
@return crypted array of 1024 bytes.
*/
DATA CryptBlockWithRSA(char _data[1024]);
};
rServer.cpp :
#include <iostream>
#include "../cryptopp562/sha.h"
#include "../cryptopp562/filters.h"
#include "../cryptopp562/hex.h"
#include <string>
#include <sstream>
#include "../cryptopp562/cryptlib.h"
using CryptoPP::Exception;
#include "../cryptopp562/hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "../cryptopp562/filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;
#include "../cryptopp562/des.h"
using CryptoPP::DES_EDE2;
#include "rServer.h";
#include "../cryptopp562/modes.h"
using CryptoPP::CBC_Mode;
#include "../cryptopp562/secblock.h"
using CryptoPP::SecByteBlock;
#include <iostream>
#include <string>
#include "../cryptopp562/modes.h"
#include "../cryptopp562/aes.h"
#include "../cryptopp562/filters.h"
#include "../cryptopp562/rsa.h"
#include <cstdint>
#include "../cryptopp562/integer.h"
#include "../cryptopp562/osrng.h"
using namespace std;
/**
Returns a crypted block of 1024 bytes with AES algorithm.
@param _data input array of 1024 bytes.
@return crypted array of 1024 bytes.
*/
DATA rServer::CryptBlockWithAESmodeCBC(char _data[1024]) {
DATA d;
char body[1024]; // ---------- il es conseillé d'utiliser allcoation dynamique: char * body =(char *) malloc(taille_de_la chaine);----------
char* entete; // entete = iv+ key
char typeAlgo[1024]="AES"; // mode CBC
char* texteChiffre;
std::string key = "0123456789abcdef";
std::string iv = "aaaaaaaaaaaaaaaa";
//string plain = "CBC Mode Test";
string cipher, encoded, recovered;
std::string plaintext = _data;
std::string ciphertext;
std::string decryptedtext;
cout<<"****************** Algorithme AES *****************"<<endl<<endl;
std::cout << " Plain Text (" << plaintext.size() << " bytes): " ;
std::cout << " "+plaintext;
std::cout << std::endl << std::endl;
CryptoPP::AES::Encryption aesEncryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, (byte *)iv.c_str() );
CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) );
stfEncryptor.Put( reinterpret_cast<const unsigned char*>( plaintext.c_str() ), plaintext.length() + 1 );
stfEncryptor.MessageEnd();
//cout << "cipher text plain: " << ciphertext << endl;
//std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" << std::endl;
texteChiffre= (char*)ciphertext.c_str();
/*std::cout <<"cipher text In HEX FORM:: ";
for( int i = 0; i < ciphertext.size(); i++ ) {
std::cout << "0x" << std::hex << (0xFF & static_cast<byte>(ciphertext[i])) << " ";
}
cout << endl;
cout << endl;*/
strcpy(d.body,texteChiffre);
strcpy(d.header.typeAlgo,typeAlgo);
char* vector=(char*)iv.c_str();
strcpy(d.header.vector,vector);
char* keyChar=(char*)key.c_str();
strcpy(d.header.key1,keyChar);
return d;
}
/**
Returns a crypted block of 1024 bytes with Blowfish algorithm.
@param _data input array of 1024 bytes.
@return crypted array.
*/
DATA rServer::CryptBlockWithBlowfish(char _data[1024]) {
DATA d;
char body[1024]; // ---------- il est conseillé d'utiliser allcoation dynamique: char * body =(char *) malloc(taille_de_la chaine);----------
char* blKeyChar; // entete = key
char typeAlgo[1024]="BLF";
char* texteChiffre;
cout<<"****************** Algorithme BlowFish ******************"<<endl<<endl;
SpaceCrypto::CryptBlowFish hello;
hello.setPlainString(_data);
hello.setKey("mySecUreKey!!");
std::string crypt;
crypt = hello.Encrypt();
cout<<" Plain Text: "<< _data <<endl;
cout << endl;
texteChiffre= (char*)crypt.c_str();
strcpy(d.body,texteChiffre);
std::string blKey=hello.getKey();
blKeyChar=(char*)blKey.c_str();
strcpy(d.header.typeAlgo,typeAlgo);
strcpy(d.header.key1,blKeyChar);
return d;
}
/**
Returns a crypted block of 1024 bytes with RSA algorithm.
@param _data input array of 1024 bytes.
@return crypted array of 1024 bytes.
*/
DATA rServer::CryptBlockWithRSA(char _data[1024]) {
DATA data;
char body[1024]; // ---------- il es conseillé d'utiliser allcoation dynamique: char * body =(char *) malloc(taille_de_la chaine);----------
char* entete; // entete = key
char typeAlgo[4]="RSA";
char* texteChiffre;
cout<<"****************** Algorithme RSA ******************"<<endl<<endl;
// Keys
// La clé publique est la paire (e, n) et la clé secrète est d, donc aussi p et q.
// p = 3, q = 11, n = 3 x 11, f = (11–1).(3–1) = 20. On choisit d=7 (7 et 20 sont bien premiers entre eux).
// e = 3 car e.d= 20 * 1 + 1
CryptoPP::Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9");
CryptoPP::RSA::PrivateKey privKey;
privKey.Initialize(n, e, d);
CryptoPP::RSA::PublicKey pubKey;
pubKey.Initialize(n,e);
//convert char _data[1024] to string
string msg;
msg= _data;
// Encryption: In RSA, encryption is simply c = me. So our task is to encode the string as an Integer in preparation for encryption.
CryptoPP::Integer m((const byte *)msg.data(), msg.size());
//m (the word secret) is encoded as an integer. We can use C++'s insertion operator to inspect m:
/*std::cout << "m: " << m << std::endl;*/
//At this point, we have n, e, d and m. To encrypt m, we perform the following.
//ApplyFunction is the 'easy to compute' transformation.
CryptoPP::Integer c = pubKey.ApplyFunction(m);
/*std::cout << "c: " << std::hex << c << std::endl;*/
// conversion CryptoPP::Integer to char*
std::stringstream ss;
ss << c;
std::string s = ss.str();
texteChiffre= (char*)s.c_str();
strcpy(data.body,texteChiffre);
strcpy(data.header.typeAlgo,typeAlgo);
return data;
}