'message hash or MAC not valid' exception after decryption

698 views Asked by At

I'm trying to make a program that encrypts files (.jpg and .avi) using the crypto++ libraries. My aim is to make a program that successfully encrypts video files using AES-256.

I did text examples of AES encryption from here and they ran successfully (meaning that the library is setup correctly). However, the following simple code produces the exception

HashVerificationFilter: message hash or MAC not valid

Code:

AutoSeededRandomPool prng;

SecByteBlock key(AES::DEFAULT_KEYLENGTH);
prng.GenerateBlock(key, key.size());

SecByteBlock iv(AES::BLOCKSIZE);
prng.GenerateBlock(iv, iv.size());

string ofilename = "testimage.png";
string efilename;
string rfilename = "testimagerecovered.png";

try
{

    GCM< AES >::Encryption e;
    e.SetKeyWithIV(key, key.size(), iv, iv.size());

    ifstream ofile(ofilename.c_str(), ios::binary);
    ofile.seekg(0, ios_base::beg);

    FileSource fs1(ofilename.c_str(), true,
            new AuthenticatedEncryptionFilter(e,
                    new StringSink(efilename)));

    GCM< AES >::Decryption d2;
    d2.SetKeyWithIV(key, key.size(), iv, sizeof(iv));

    StringSource fs2(efilename, true,
            new AuthenticatedDecryptionFilter( d2,
                    new FileSink (rfilename.c_str()),
                    AuthenticatedDecryptionFilter::THROW_EXCEPTION));
}
catch(const Exception &e)
{
    cerr << e.what() << endl;
    exit(1);
}

return 0;

I suspect I am not implementing the AES algorithm correctly. However, I am unable to find a solution for the last two days. I'm using Eclipse Luna on Ubuntu 14.04.

PS I have gone through the following answers

How to read an image to a string for encrypting Crypto++

How to loop over Blowfish Crypto++

1

There are 1 answers

3
Eric Tsui On BEST ANSWER

Please use iv.size() rather than sizeof(iv) when you try to set d2.SetKeyWithIV, just like what you have done to e.SetKeyWithIV. Because in this program, the value of iv.size() is 16, but sizeof(iv) is 24. Then it will work.

GCM< AES >::Decryption d2;
d2.SetKeyWithIV(key, key.size(), iv, iv.size()); //here was a misuse of sizeof(iv)

StringSource fs2(efilename, true,
        new AuthenticatedDecryptionFilter( d2,
                new FileSink (rfilename.c_str()),
                AuthenticatedDecryptionFilter::THROW_EXCEPTION));

The code which has passed my test is as above.