I have a simple program that encrypts and decrypts text from input gotten from a text file. When I encrypt and decrypt in one cycle, I get the desired result, but if I encrypt, close application then re-run application, this time decrypt, the process fails.
The decryption snippet looks like this :
string decoded, plainText;
string fileData((istreambuf_iterator<char>(fileDecrypt)), (istreambuf_iterator<char>()));
ECB_Mode<AES>::Decryption decryption;
decryption.SetKey((byte*)key.c_str(), sizeof(key));
StringSource(fileData, true, new HexDecoder(new StringSink(decoded)));
StringSource(decoded, true, new StreamTransformationFilter(decryption, new StringSink(plainText)));
When I run debugger in VS2010, I get error on the last line
StringSource(decoded, true, new StreamTransformationFilter(decryption, new StringSink(plainText)));
When I wrap a try-catch block around decrypt function, I get this error
StreamTransformationFilter: invalid PKCS #7 block padding found
Not sure why it works if I encrypt and decrypt in one build, but fail if I try to decrypt without first encrypting first on the same run.
ECB_Mode<AES>::Decryption decryption;
ECB mode operates on a full block size, and no padding is required.
You can pad it, but it does not look like you are doing so. The caveat is the plain text must be a multiple of 16, which is AES's blocksize.
When I wrap a try-catch block around decrypt function, I get this error
StreamTransformationFilter: invalid PKCS #7 block padding found
That's because you are padding it in:
StreamTransformationFilter(decryption, new StringSink(...)).
StreamTransformationFilter
has a padding parameter. As you probably realize, it is BlockPaddingScheme::PKCS_PADDING
Try:
ECB_Mode<AES>::Decryption decryption;
decryption.SetKey((byte*)key.data(), key.size());
std::string plainText;
StreamTransformationFilter filter(decryption, new StringSink(plainText),
StreamTransformationFilter::NO_PADDING);
FileSource fs(filename.c_str(), true, new HexDecoder(new Redirector(filter)));
...
Other errata:
ECB_Mode<AES>::Decryption decryption; decryption.SetKey((byte*)key.c_str(), sizeof(key));
sizeof(key)
is wrong. Use 16, 24, or 32. If the std::string
is properly sized, then you can use key.size()
.
And name you objects. I've seen GCC generate bad code with Crypto++:
ECB_Mode<AES>::Decryption decryption;
StringSource ss1(fileData, ...);
StringSource ss2(decoded, ...);
And a quick warning....
ECB mode is usually wrong. I'm not saying it is in this case, or that you are wrong. But you might want to have a look at EAX mode
, GCM mode
or CCM mode
. My apologies if this is more than it seems.
Even better, use a scheme like Elliptic Curve Integrated Encryption Scheme (ECIES) or Discrete Logarithm Integrated Encryption Scheme (DLIES). The schemes are IND-CCA, which is a very strong notion of security.
When using ECIES or DLIES, your problem reduces to sharing the public keys. But you have that problem now with the symmetric keys, so its a lateral move for key distribution, and a win for encryption.