andreyvit (andreyvit) wrote,

Crypto++

(Posting in English in the hope this might be useful for someone else.) Crypto++ is one of the most complete and powerful cryptography libraries for C++. The only problem with it is a lack of a full introductory example. At least I could not figure out how to use it after an hour of searching and studying different resources. So, here is a full working example: 

#include <cryptopp/blowfish.h>
#include <cryptopp/base64.h>
#include <cryptopp/files.h>
#include <cryptopp/filters.h>
#include <cryptopp/modes.h>
#include <cryptopp/gzip.h>
#include <cryptopp/osrng.h>
#include <cryptopp/hex.h>

#include <wf/globals.hpp>
#include <iostream>
#include <exception>

using namespace CryptoPP;

void main () {
    byte key[CryptoPP::Blowfish::DEFAULT_KEYLENGTH], iv[CryptoPP::Blowfish::BLOCKSIZE];
    std::string plainText;

    plainText = "Hello, world!";
    for (int i = 0; i < 10; i++) {
        plainText = plainText + plainText;
    }

    CryptoPP::AutoSeededRandomPool rng (true);
    rng.GenerateBlock(key, sizeof (key));
    rng.GenerateBlock(iv, sizeof (iv));

    std::string cipher;
    {
        CryptoPP::StringSink* sink = new CryptoPP::StringSink(cipher);
        CryptoPP::Base64Encoder* base64_enc = new CryptoPP::Base64Encoder(sink);
        CryptoPP::CBC_Mode<CryptoPP::Blowfish>::Encryption twofish(key, CryptoPP::Blowfish::DEFAULT_KEYLENGTH, iv);
        CryptoPP::StreamTransformationFilter* enc = new CryptoPP::StreamTransformationFilter(twofish, base64_enc);
        CryptoPP::Gzip *zip = new CryptoPP::Gzip (enc);
        CryptoPP::StringSource source(plainText, true, zip);
    }

    std::cout << "Key length: " << (countof(key)*8) << std::endl;
    std::cout << "IV length: " << (countof(iv)*8) << std::endl;
    std::cout << "Encrypted text:\n" << cipher << std::endl;

    //rng.GenerateBlock(iv, sizeof (iv));
    //rng.GenerateBlock(key, sizeof (key));

    std::string decipher;
    try {
        CryptoPP::StringSink* sink = new CryptoPP::StringSink(decipher);
        CryptoPP::Gunzip *unzip = new CryptoPP::Gunzip (sink);
        CryptoPP::CBC_Mode<CryptoPP::Blowfish>::Decryption twofish(key, CryptoPP::Blowfish::DEFAULT_KEYLENGTH, iv);
        CryptoPP::StreamTransformationFilter* dec = new CryptoPP::StreamTransformationFilter(twofish, unzip);
        CryptoPP::Base64Decoder* base64_dec = new CryptoPP::Base64Decoder(dec);
        CryptoPP::StringSource source(cipher, true, base64_dec);
    } catch (const std::exception &e) {
        std::cout << "unsuccessful! caught " << "unknown" << ": " << e.what() << std::endl;
    } catch (...) {
        std::cout << "unsuccessful!" << std::endl;
    }
    std::cout << "Decrypted text:\n" << decipher.substr(0, 70) << "..." << std::endl;

    std::string skey;
    {
        CryptoPP::StringSink *sink = new CryptoPP::StringSink (skey);
        CryptoPP::HexEncoder enc (sink);
        enc.Put(key, sizeof(key));
    }
    std::cout << "Key: " << skey;
}

This code assumes you have Crypto++ installed in cryptopp subdirectory of some directory which is listed in include directories on your compiler's command line. E.g., if you invoke the compiler as "cl -Ic:/devel/src", then Crypto++ must be in "c:/devel/src/cryptopp".

Tags: crypto, programming, samples
  • Post a new comment

    Error

    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded  

  • 22 comments