I've spent some time (too much) on the C++ side of my application, and have 
pinned down where the problem seems to be; recovering the initialization 
vector from a passed hex string representation.  Below is the (uncommented) 
code I've been working with.

*Aes.h:*
#ifndef AES_H_
#define AES_H_

#include "cryptopp/modes.h"
#include "cryptopp/aes.h"
#include "cryptopp/osrng.h"
#include "cryptopp/pwdbased.h"
#include "cryptopp/hex.h"
#include "cryptopp/base64.h"

using namespace std;
using namespace CryptoPP;

class Aes {
public:
Aes();
virtual ~Aes();

private:
string _cipherText;
string _recoveredText;

// secret key
SecByteBlock _derivedKey;  // TODO get better name

// initialization vector
// AES IV is 16 bytes, 128 bits
//byte   _iv[AES::BLOCKSIZE];
SecByteBlock _iv;

public:
void createRandomIV();
void createKey();
void encrypt(string clearText);
void encrypt(string clearText, byte *iv);
void encrypt(string clearText, SecByteBlock iv);
void decrypt();
void decrypt(string cipherTextHex);
void decrypt(string cipherTextHex, string ivHex);

const SecByteBlock& getIv() const {
return _iv;
}

void setIv(SecByteBlock iv) {
_iv = iv;
}

const SecByteBlock& getDerivedKey() const {
return _derivedKey;
}

void setDerivedKey(SecByteBlock derivedKey) {
_derivedKey = derivedKey;
}

const string& getCipherText() const {
return _cipherText;
}

void setCipherText(const string& cipherText) {
_cipherText = cipherText;
}

const string& getRecoveredText() const {
return _recoveredText;
}

void setRecoveredText(const string& recoveredText) {
_recoveredText = recoveredText;
}
};

#endif /* AES_H_ */


*Aes.cpp:*
#include "Aes.h"

Aes::Aes() {
}

Aes::~Aes() {
}

void Aes::createRandomIV() {
AutoSeededRandomPool rnd;
SecByteBlock iv(AES::BLOCKSIZE);

rnd.GenerateBlock(iv, AES::BLOCKSIZE);
setIv(iv);
}

void Aes::createKey() {
string password = "This is my password";
byte *passwordBytes = (byte *) password.data();

// 128 bit/16 byte salt
// AES::DEFAULT_KEYLENGTH = 16
// salt modified for post
byte salt[] = { (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
(byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
(byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
(byte) 0x0f, (byte) 0x10 };

// number of iterations for key derivation
int iterations = 65536;

// derive key from password and salt
//SecByteBlock derivedKey(32); // 256 bits, default is 128 bits/16 bytes
SecByteBlock derivedKey(AES::DEFAULT_KEYLENGTH);

PKCS5_PBKDF2_HMAC<SHA1> pbkdf;
pbkdf.DeriveKey(derivedKey, derivedKey.size(), 0x00, passwordBytes,
password.size(), salt, sizeof(salt), iterations);
setDerivedKey(derivedKey);
}

void Aes::encrypt(string clearText) {
SecByteBlock key = getDerivedKey();
string cipherText;

CBC_Mode<AES>::Encryption encryptor(key, key.size(), getIv());
StringSource(clearText, true,
new StreamTransformationFilter(encryptor,
new StringSink(cipherText)));
setCipherText(cipherText);
}

void Aes::encrypt(string clearText, SecByteBlock iv) {
SecByteBlock key = getDerivedKey();
string cipherText;

CBC_Mode<AES>::Encryption encryptor(key, key.size(), iv);
StringSource(clearText, true,
new StreamTransformationFilter(encryptor,
new StringSink(cipherText)));
setCipherText(cipherText);
}

void Aes::decrypt() {
SecByteBlock key = getDerivedKey();
string recoveredText;

CBC_Mode<AES>::Decryption decryptor(key, key.size(), getIv());
StringSource(getCipherText(), true,
new StreamTransformationFilter(decryptor,
new StringSink(recoveredText)));

setRecoveredText(recoveredText);
}

void Aes::decrypt(string cipherTextHex) {
SecByteBlock key = getDerivedKey();
string recoveredText;

CBC_Mode<AES>::Decryption decryptor(key, key.size(), getIv());
StringSource(cipherTextHex, true,
new HexDecoder(
new StreamTransformationFilter(decryptor,
new StringSink(recoveredText))));

setRecoveredText(recoveredText);
}

// not working
void Aes::decrypt(string cipherTextHex, string ivHex) {
string recoveredText;
SecByteBlock recoverediv(AES::BLOCKSIZE);
SecByteBlock key = getDerivedKey();

StringSource ivDecoder(ivHex, true,
new HexDecoder(new ArraySink(recoverediv, recoverediv.size())));

CFB_Mode<AES>::Decryption decryptor(key, key.size(), recoverediv);
StringSource(cipherTextHex, true,
new HexDecoder(
new StreamTransformationFilter(decryptor,
new StringSink(recoveredText))));

setRecoveredText(recoveredText);
}

*main.cpp:*
// test the Aes class

#include <iostream>
#include <string>

#include "Aes.h"

#include "ServerSocket.h"
#include "SocketException.h"

int main(int argc, char *argv[]) {
Aes *aes = new Aes();

aes->createRandomIV();
SecByteBlock iv = aes->getIv();

aes->createKey();
// aes->encrypt("Hello! How are you."); // works
aes->encrypt("Hello! How are you.", iv); // works
// aes->decrypt(); // works

string ivHex;
string cipherHex;

// both encoders, String or Array Source, work
StringSource(iv, iv.size(), true,
new HexEncoder(new StringSink(ivHex), false)
);
// ArraySource(iv, iv.size(), true,
// new HexEncoder(new StringSink(ivHex), false)
// );

StringSource(aes->getCipherText(), true,
new HexEncoder(new StringSink(cipherHex), false)
);

cout << "        " << iv.size() << endl;
// cout << "iv:     " << iv << endl;
cout << "        " << ivHex.length() << endl;
cout << "iv hex: " << ivHex << std::endl;
cout << "cipher: " << aes->getCipherText() << endl;
cout << "ciphHex:" << cipherHex << endl;

aes->decrypt(cipherHex); // works
cout << "Recovered text 1: " << aes->getRecoveredText() << std::endl;

aes->decrypt(cipherHex, ivHex); // fails
cout << "Recovered text 2: " << aes->getRecoveredText() << std::endl;

delete (aes);

return 0;
}


-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to