问题
I am trying to use AES encryption from Crypto++ libary:
CBC_Mode<AES>::Encryption e;
I have a binary data block that I need to encrypt. The class seems to provide a method called ProcessData
for this purpose:
virtual void ProcessData(byte *outString, const byte *inString, size_t length);
Looks like the last parameter is the size of the input data. What is not clear is why the method does not return me the size of the encrypted data. Is it assumed that the size of output data block is exactly the same as the length of input data block? Is this valid even if the size of input data is just one byte? Regards.
回答1:
virtual void ProcessData(byte *outString, const byte *inString, size_t length);
Looks like the last parameter is the size of the input data. What is not clear is why the method does not return me the size of the encrypted data...
ProcessData
is the workhorse of all block ciphers (but not stream ciphers or other types of objects). Also see the Crypto++ manual and cryptlib.h File Reference. cryptlib.h
is described as "Abstract base classes that provide a uniform interface to this library".
ProcessData
operates on block-sized lengths of data. So INSIZE
is equal to OUTSIZE
is equal to BLOCKSIZE
. Note that there is no INSIZE
or OUTSIZE
- I used them for discussion. Each block cipher will provide a constant for BLOCKSIZE
. There will be a AES::BLOCKSIZE
, DES_EDE::BLOCKSIZE
, etc.
Typically you do not use ProcessData
directly. You can use it directly, but you will be responsible for all the associated details (more on the details below).
Typically you use a StreamTransformationFilter
, but its not readily apparent why. StreamTransformationFilter
provides input buffering, output buffering, and padding as required. Its briefly discussed at Init-Update-Final on the wiki.
Here's how it looks in practice from the CBC mode example on the Crypto++ wiki:
try
{
cout << "plain text: " << plain << endl;
CBC_Mode< AES >::Encryption e;
e.SetKeyWithIV( key, key.size(), iv );
// The StreamTransformationFilter adds padding
// as required. ECB and CBC Mode must be padded
// to the block size of the cipher.
StringSource ss( plain, true,
new StreamTransformationFilter( e,
new StringSink( cipher )
) // StreamTransformationFilter
); // StringSource
}
catch( const CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
In the above, CBC_mode
and StreamTransformationFilter
work together to give you desired results. CBC_mode
calls ProcessData
and handles the cipher chaining details. StreamTransformationFilter
feeds the plain text in its preferred size. If there's not enough plain text, then StreamTransformationFilter
buffers it on input. If there's no output buffer, then StreamTransformationFilter
buffers cipher text, too.
StreamTransformationFilter
will also apply padding as required. There's a default padding, but you can override it. StreamTransformationFilter
knows what padding to apply because it asks the mode (CBC_mode
) if the padding is required and what the padding should be.
... Is it assumed that the size of output data block is exactly the same as the length of input data block? Is this valid even if the size of input data is just one byte?
This is where the StreamTransformationFilter
fits into the equation.
Be sure to check out Init-Update-Final on the wiki. It should provide the glue for you if you are used to Java or OpenSSL programming. It should help "make it click" for you.
来源:https://stackoverflow.com/questions/37685190/crypto-output-data-length