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; }