Skipping last few bytes of file when FileSource

48 views
Skip to first unread message

Richard Závodný

unread,
Nov 5, 2017, 10:00:06 AM11/5/17
to Crypto++ Users
Hi. I need skip last 512bytes from the file. This solution not working:
int fileSize = boost::filesystem::file_size("first.txt");

CryptoPP
::FileSource sourceFile("first.txt", false, new CryptoPP::FileSink("second.txt"));
sourceFile.Pump(fileSize - 512);

How could i achieve this?

Jeffrey Walton

unread,
Nov 6, 2017, 8:37:30 AM11/6/17
to Crypto++ Users
Pump as many bytes as you wish. Then, call sourceFile.Skip(...) to skip the bytes.

Also see BufferedTransformation in the docs at https://www.cryptopp.com/docs/ref/class_buffered_transformation.html.

Jeff

Richard Závodný

unread,
Nov 6, 2017, 2:27:30 PM11/6/17
to Crypto++ Users
Okay. I think, there is another problem. The file is actually splitted into two parts. First is encrypted content using AES and the second is encrypted Aes Key and Iv using RSA. The encrypted Aes Key and Iv is 512 bytes big on the end. First I needed to get 512 bytes from the end, decrypt using RSA then I get the AES key and iv. That isn't problem. I did what you proposed. Code following:
CryptoPP::FileSource sourceFile("first.txt", false, new CryptoPP::StreamTransformationFilter(cbcDecryptor, new CryptoPP::FileSink("second.txt")));
sourceFile.Pump(fileSize - 512); //Fetch only encrypted content with AES (without the RSA encrypted key)
sourceFile
.Skip(512); //Skip last 512 bytes

But when I do this, the problem occur. My decrypted file is 15 bytes shorter and I don't know why! Original file size is 351 bytes, encrypted is 864 bytes (351 bytes + 1byte AES padding + 512 bytes key), decrypted file size is 336 bytes.

Jeffrey Walton

unread,
Nov 6, 2017, 3:28:38 PM11/6/17
to Crypto++ Users


On Monday, November 6, 2017 at 2:27:30 PM UTC-5, Richard Závodný wrote:
Okay. I think, there is another problem. The file is actually splitted into two parts. First is encrypted content using AES and the second is encrypted Aes Key and Iv using RSA. The encrypted Aes Key and Iv is 512 bytes big on the end. First I needed to get 512 bytes from the end, decrypt using RSA then I get the AES key and iv. That isn't problem. I did what you proposed. Code following:
CryptoPP::FileSource sourceFile("first.txt", false, new CryptoPP::StreamTransformationFilter(cbcDecryptor, new CryptoPP::FileSink("second.txt")));
sourceFile.Pump(fileSize - 512); //Fetch only encrypted content with AES (without the RSA encrypted key)
sourceFile
.Skip(512); //Skip last 512 bytes

But when I do this, the problem occur. My decrypted file is 15 bytes shorter and I don't know why! Original file size is 351 bytes, encrypted is 864 bytes (351 bytes + 1byte AES padding + 512 bytes key), decrypted file size is 336 bytes.

It sounds like data is being buffered: 351 -336 = 15.

Try calling sourceFile.MessageEnd(). If you get an exception, then you will need to use a different technique.

Since you are at the end of your data stream you may be able to induce a MessageEnd() with a call to PumpAll().

You can wrap the code above in a C++ block to cause the destructors to run, which will implicitly call MessageEnd():

{
    FileSource sourceFile("first.txt", false, ...);
    sourceFile.Pump(fileSize - 512);
    sourceFile.Skip(512);
}

If you want to explicitly control MessageEnd(), then use the following. It is how the library does it when needed:

StreamTransformationFilter* x = NULL;
FileSource sourceFile("first.txt", false, x=new StreamTransformationFilter(...));
sourceFile.Pump(fileSize - 512);
sourceFile.Skip(512);
x->MessageEnd();

Jeff

Richard Závodný

unread,
Nov 7, 2017, 9:11:19 AM11/7/17
to Crypto++ Users
Thanks much! The last example works well.. :)
Reply all
Reply to author
Forward
0 new messages