Crypto++ “Tee”-style filter

南笙酒味 提交于 2020-01-04 21:39:28

问题


I'm working on processing a data-stream based on some conditions.

Data is read from an input pipe, processed, and pushed down a Crypto++ CBC_Mode<AES> filter ending in a FileSink.

Now, I'd like to "snoop" on the data flowing between the encryption and file-store, calculating a checksum. For performance reasons, I want to do this while streaming, re-opening the output file and calculating a hash-sum after is not reasonable for my need.

From what I can see, what's missing for this to work, is some form of "tee" filter. Something splitting the data chain into two new chains, one for storing to file, and one chain for the hash-calculation.

Are there such functionality in Crypto++? Can I implement such filter myself, and if so, are there some guidelines or examples on what's needed for a custom Crypto++ filter? Are there some other way to calculate checksum on the fly?


回答1:


From what I can see, what's missing for this to work, is some form of "tee" filter. ... Are there such functionality in Crypto++?

Yes, its called a ChannelSwitch. The following is from the Crypto++ wiki page on ChannelSwitch, and it follows Wei Dai's use of the class in his test files.

MD5 hashMD5;
HashFilter filterMD5(hashMD5);

SHA1 hashSHA1;
HashFilter filterSHA1(hashSHA1);

std::auto_ptr<ChannelSwitch> channel( new ChannelSwitch );

channel->AddDefaultRoute(filterMD5);
channel->AddDefaultRoute(filterSHA1);

StringSource ss( "abcdefghijklmnopqrstuvwxyz", true, channel.release());

string digest;
HexEncoder encoder( new StringSink( digest ), true /* uppercase */ ); 

filterMD5.TransferTo( encoder );
cout << filterMD5.AlgorithmName() << ": " << digest << endl;
digest.erase();

filterSHA1.TransferTo( encoder );
cout << filterSHA1.AlgorithmName() << ": " << digest << endl;
digest.erase();

Here's the output of the example above:

$ ./cryptopp-test.exe
MD5: C3FCD3D76192E4007DFB496CCA67E13B
SHA-1: 32D10C7B8CF96570CA04CE37F2A19D84240D3A89

Here's another example that uses distinct sinks and might be easier to follow:

byte data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
string e1, e2, e3;

HexEncoder r1(new StringSink(e1));
Base32Encoder r2(new StringSink(e2));
Base64Encoder r3(new StringSink(e3));

ChannelSwitch chsw;
chsw.AddDefaultRoute(r1);
chsw.AddDefaultRoute(r2);
chsw.AddDefaultRoute(r3);

chsw.Put(data, sizeof(data));
chsw.MessageEnd();

cout << e1 << endl;
cout << e2 << endl;
cout << e3 << endl;

Here's the output of the example:

$ ./cryptopp-test.exe
0102030405060708090A
AEBAGBAFA2DSSCIK
AQIDBAUGBwgJCg==


来源:https://stackoverflow.com/questions/10732926/crypto-tee-style-filter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!