AES Encrypt/Decrypt using cryptopp(crypto++)
ITWeb/개발일반 2013. 2. 5. 14:24This article referenced the below URL.
http://www.mimul.com/pebble/default/2009/02/27/1235731380000.html
http://www.cryptopp.com/
http://www.cryptopp.com/wiki/Advanced_Encryption_Standard
http://www.cryptopp.com/wiki/Category:Sample
[cryptopp installation]
wget http://sourceforge.net/projects/cryptopp/files/latest/download?source=dlp
unzip cryptopp561.zip -d cryptopp
cd cryptopp
make
ls -al
# You can find "libcryptopp.a" and "*.h".
[g++ options]
g++ aesCfbMode.cpp -I./cryptopp ./cryptopp/libcryptopp.a -lssl -lcrypto -lrt -lm -o aesCfbMode
I need to encrypt/decrypt using AES CFB mode.
The below code is to use AES CFB mode.
[aesCfbMode.cpp]
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "osrng.h"
using CryptoPP::AutoSeededRandomPool;
#include <iostream>
#include <sstream>
#include <fstream>
using std::ifstream;
using std::ofstream;
using std::cout;
using std::cerr;
using std::endl;
using std::ios;
using std::filebuf;
#include <string>
using std::string;
#include <cstdlib>
using std::exit;
#include "cryptlib.h"
using CryptoPP::Exception;
#include "hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::StreamTransformationFilter;
#include "aes.h"
using CryptoPP::AES;
#include "modes.h"
using CryptoPP::CFB_Mode;
const int32_t BUFFER_SIZE = 32;
void hex2byte(const char *in, uint len, byte *out)
{
for (uint i = 0; i < len; i+=2) {
char c0 = in[i+0];
char c1 = in[i+1];
byte c = (
((c0 & 0x40 ? (c0 & 0x20 ? c0-0x57 : c0-0x37) : c0-0x30)<<4) |
((c1 & 0x40 ? (c1 & 0x20 ? c1-0x57 : c1-0x37) : c1-0x30))
);
out[i/2] = c;
}
}
int main(int argc, char* argv[]) {
FILE *isfp;
FILE *osfp;
ifstream is, cis;
ofstream os, cos;
char rBuff[BUFFER_SIZE] = {"\0",};
char wBuff[BUFFER_SIZE] = {"\0",};
int readSize = 0;
int currSize=0, totalSize=0, extraSize=0, buffSize=0;
string plain, cipher, encoded, recovered;
//
// 키 할당
//
byte key[CryptoPP::AES::DEFAULT_KEYLENGTH];
memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
char* rawKey="f4150d4a1ac5708c29e437749045a39a";
hex2byte(rawKey, strlen(rawKey), key);
// IV 할당
byte iv[CryptoPP::AES::BLOCKSIZE];
memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE );
char* rawIv="86afc43868fea6abd40fbf6d5ed50905";
hex2byte(rawIv, strlen(rawIv), iv);
// Pretty print key
encoded.clear();
StringSource(key, sizeof(key), true,
new HexEncoder(
new StringSink(encoded)
) // HexEncoder
); // StringSource
cout << "key: " << encoded << endl;
// Pretty print iv
encoded.clear();
StringSource(iv, sizeof(iv), true,
new HexEncoder(
new StringSink(encoded)
) // HexEncoder
); // StringSource
cout << "iv: " << encoded << endl;
// encryption scope
try {
CFB_Mode< AES >::Encryption e;
e.SetKeyWithIV(key, sizeof(key), iv);
is.open("plain.txt", ifstream::binary);
os.open("cipher.txt", ofstream::ate|ofstream::binary);
// get file size
is.seekg (0, ios::end);
totalSize = is.tellg();
is.seekg (0, ios::beg);
cout << "totalSize is : " << totalSize << endl;
while( !is.eof() ) {
// calculate extra file size after read file
// divide by function from here
extraSize = totalSize - currSize;
if ( extraSize >= BUFFER_SIZE ) {
buffSize = BUFFER_SIZE;
} else {
buffSize = extraSize;
}
currSize = currSize + buffSize;
// initial read buffer
memset(rBuff, 0x00, sizeof(rBuff));
is.read(rBuff, BUFFER_SIZE);
// char array to string
plain = string(rBuff, buffSize);
#if 0
StringSource(plain, true,
new StreamTransformationFilter(e,
new StringSink(cipher)
) // StreamTransformationFilter
); // StringSource
#endif
#if 1
StreamTransformationFilter filter(e);
filter.Put((const byte*)plain.data(), plain.size());
filter.MessageEnd();
const size_t ret = filter.MaxRetrievable();
cipher.resize(ret);
filter.Get((byte*)cipher.data(), cipher.size());
#endif
os.write(cipher.c_str(), cipher.size());
}
is.close();
os.close();
} catch(const CryptoPP::Exception& e) {
cerr << e.what() << endl;
exit(1);
}
// decryption scope
try {
CFB_Mode< AES >::Decryption d;
d.SetKeyWithIV(key, sizeof(key), iv);
isfp = fopen("cipher.txt", "rb");
cos.open("plain_decrypt.txt", ofstream::ate | ofstream::binary);
struct stat buf;
fstat(fileno(isfp), &buf);
totalSize = buf.st_size;
currSize=0;
extraSize=0;
buffSize=0;
while ( !feof(isfp) ) {
// calculate extra file size after read file
// divide by function from here
extraSize = totalSize - currSize;
if ( extraSize >= BUFFER_SIZE ) {
buffSize = BUFFER_SIZE;
} else {
buffSize = extraSize;
}
currSize = currSize + buffSize;
// initial read buffer
memset(rBuff, 0x00, sizeof(rBuff));
fread(rBuff, 1, BUFFER_SIZE, isfp);
// char array to string
cipher = string(rBuff, buffSize);
#if 0
StringSource s(cipher, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
) // StreamTransformationFilter
); // StringSource
#endif
#if 1
StreamTransformationFilter filter(d);
filter.Put((const byte*)cipher.data(), cipher.size());
filter.MessageEnd();
const size_t ret = filter.MaxRetrievable();
recovered.resize(ret);
filter.Get((byte*)recovered.data(), recovered.size());
#endif
cos.write(recovered.c_str(), recovered.size());
}
} catch(const CryptoPP::Exception& e) {
cerr << e.what() << endl;
exit(1);
}
fclose(isfp);
cos.close();
return 0;
}
[cryptopp change]
rename zlib.cpp to zlibcryptopp.cpp
rename zlib.h to zlibcryptopp.h
modified "zlib.h" to "zlibcryptopp.h"