I have the following code, basically grabbed right from the Crypto++ wiki at http://www.cryptopp.com/wiki/AuthenticatedDecryptionFilter
The problem is, with the output I get "plaintext: abc1230000000077C8E390" instead of what I'd expect, just "plaintext: abc123"
What is the extra data at the end?
Also- two more small questions that are based on the same codebase:
would this method serve as a drop-in replacement for using actual random byte data for pdata- or since it's string must it actually be like usual text?
I assume adata is meant to be transferred in plaintext, so when storing the ciphertext, am I correct that both the iv and adata are in plaintext, and the user only provides the key (to decrypt the ciphertext with those 4 elements: key (provided by user), ciphertext (made available), iv (made available), and adata (made available)?
Thank you!
AutoSeededRandomPool prng;
byte key[ AES::DEFAULT_KEYLENGTH ];
prng.GenerateBlock( key, sizeof(key) );
byte iv[ AES::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );
string adata( 16, (char)0x00 );
string cipherText = encryptData("abc123", adata, key, iv);
string plainText = decryptData(cipherText, adata, key, iv);
cout << "plaintext: " << plainText << endl;
//Utilities
string MainWindow::encryptData(string pdata, string adata, const byte *key, const byte *iv) {
const int TAG_SIZE = 16;
string cipher;
try
{
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, AES::DEFAULT_KEYLENGTH, iv, AES::BLOCKSIZE );
AuthenticatedEncryptionFilter ef( e,
new StringSink( cipher ), false, TAG_SIZE
); // AuthenticatedEncryptionFilter
ef.ChannelPut( "AAD", (const byte*)adata.data(), adata.size() );
ef.ChannelMessageEnd("AAD");
ef.ChannelPut( "", (const byte*)pdata.data(), pdata.size() );
ef.ChannelMessageEnd("");
}
catch( CryptoPP::BufferedTransformation::NoChannelSupport& e )
{
cerr << "Caught NoChannelSupport..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::AuthenticatedSymmetricCipher::BadState& e )
{
cerr << "Caught BadState..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::InvalidArgument& e )
{
cerr << "Caught InvalidArgument..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
return(cipher);
}
string MainWindow::decryptData(string cipher, string adata, const byte *key, const byte *iv) {
const int TAG_SIZE = 16;
string radata, rpdata;
try
{
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, AES::DEFAULT_KEYLENGTH, iv, AES::BLOCKSIZE );
string enc = cipher.substr( 0, cipher.length()-TAG_SIZE );
string mac = cipher.substr( cipher.length()-TAG_SIZE );
assert( cipher.size() == enc.size() + mac.size() );
assert( enc.size() == pdata.size() );
assert( TAG_SIZE == mac.size() );
radata = adata;
AuthenticatedDecryptionFilter df( d, NULL,
AuthenticatedDecryptionFilter::MAC_AT_BEGIN |
AuthenticatedDecryptionFilter::THROW_EXCEPTION, TAG_SIZE );
df.ChannelPut( "", (const byte*)mac.data(), mac.size() );
df.ChannelPut( "AAD", (const byte*)adata.data(), adata.size() );
df.ChannelPut( "", (const byte*)enc.data(), enc.size() );
df.ChannelMessageEnd( "AAD" );
df.ChannelMessageEnd( "" );
string retrieved;
size_t n = (size_t)df.MaxRetrievable();
retrieved.resize( n );
if( n > 0 ) { df.Get( (byte*)retrieved.data(), n ); }
rpdata = retrieved;
assert( rpdata == pdata );
}
catch( CryptoPP::InvalidArgument& e )
{
cerr << "Caught InvalidArgument..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::AuthenticatedSymmetricCipher::BadState& e )
{
cerr << "Caught BadState..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
catch( CryptoPP::HashVerificationFilter::HashVerificationFailed& e )
{
cerr << "Caught HashVerificationFailed..." << endl;
cerr << e.what() << endl;
cerr << endl;
}
return rpdata;
}