问题
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