AES Encrypt/Decrypt using cryptopp(crypto++)

ITWeb/개발일반 2013. 2. 5. 14:24

This 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"



: