ChannelSwitch
The ChannelSwitch allows you to process data in parallel by pumping it to multiple filters or sinks. It also allows you to combine multiple inputs into a single output through the use of named channels.
Documentation |
#include <cryptopp/channels.h>
|
Construction
ChannelSwitch () ChannelSwitch (BufferedTransformation &destination) ChannelSwitch (BufferedTransformation &destination, const std::string &outChannel)
destination
is a BufferedTransformation, such as another filter or sink.
outChannel
is the name of the channel to use when pipelining data to the destination. Use this constructor if you don't want to use DEFAULT_CHANNEL
.
Note: unlike many filters and sinks, the ChannelSwitch
takes a reference and not a pointer. Since ChannelSwitch
takes a reference, the caller owns the destination object. The caller is responsible for destroying the destination. Also see ownership on the Crypto++ wiki.
Example
Below are two examples of using a ChannelSwitch
. The first pumps string data to four hashes, and the second performs SSH-style authenticated encryption. SSH-style authenticated encryption is known as Encrypt-and-Authenticate (E&A). In general, you should avoid this style of authenticated encryption.
Multiple Hashes
The example below pumps string data to four hashes and then outputs the results.
#include <iostream> #include <cstring> #include <cryptopp/channels.h> #include <cryptopp/filters.h> #include <cryptopp/sha.h> #include <cryptopp/hex.h> int main(int argc, char *argv[]) { using namespace CryptoPP; std::string message = "Now is the time for all good men to come to the aide of their country"; // Allow user to override default message from command line arg. if(argc == 2 && argv[1] != NULL) message = std::string(argv[1]); // Set hash variables std::string s1, s2, s3, s4; SHA1 sha1; SHA224 sha224; SHA256 sha256; SHA512 sha512; // Run hash functions HashFilter f1(sha1, new HexEncoder(new StringSink(s1))); HashFilter f2(sha224, new HexEncoder(new StringSink(s2))); HashFilter f3(sha256, new HexEncoder(new StringSink(s3))); HashFilter f4(sha512, new HexEncoder(new StringSink(s4))); // Set route to default ChannelSwitch cs; cs.AddDefaultRoute(f1); cs.AddDefaultRoute(f2); cs.AddDefaultRoute(f3); cs.AddDefaultRoute(f4); StringSource ss(message, true /*pumpAll*/, new Redirector(cs)); std::cout << "Message: " << message << std::endl; std::cout << "SHA-1: " << s1 << std::endl; std::cout << "SHA-224: " << s2 << std::endl; std::cout << "SHA-256: " << s3 << std::endl; std::cout << "SHA-512: " << s4 << std::endl; }
A run of the program produces the results shown below:
$ ./cryptopp-test.exe password Message: password SHA-1: 5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8 SHA-224: D63DC919E201D7BC4C825630D2CF25FDC93D4B2F0D46706D29038D01 SHA-256: 5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8 SHA-512: B109F3BBBC244EB82441917ED06D618B9008DD09B3BEFD1B5E07394C706A8BB9 80B1D7785E5976EC049B46DF5F1326AF5A2EA6D103FD07C95385FFAB0CACBC86
SSH-style AuthEnc
The example below performs SSH-style authenticated encryption and then outputs the results. The SSH-style is Authenticate-then-Encrypt (AtE). You should avoid this style of authenticated encryption because its provably insecure.
// Message to encrypt and authenticate string message = "Now is the time for all good men to come to the aide of their country"; if(argc == 2 && argv[1] != NULL) message = string(argv[1]); // Setup Keys and IV SecByteBlock ekey(16), iv(16), hkey(16); memset(ekey, 0x00, ekey.size()); memset(iv, 0x00, iv.size()); memset(hkey, 0x00, hkey.size()); // Print Keys and IV HexEncoder encoder(new FileSink(cout)); cout << "Encryption key: "; encoder.Put(ekey, ekey.size()); encoder.MessageEnd(); cout << endl; cout << "Encryption iv: "; encoder.Put(iv, iv.size()); encoder.MessageEnd(); cout << endl; cout << "HMAC key: "; encoder.Put(hkey, hkey.size()); encoder.MessageEnd(); cout << endl; // Setup and key objects string s1, s2; HMAC<SHA256> hmac; CBC_Mode<AES>::Encryption encryptor; encryptor.SetKeyWithIV(ekey, ekey.size(), iv, iv.size()); hmac.SetKey(hkey, hkey.size()); // Create filters StreamTransformationFilter ef(encryptor, new HexEncoder(new StringSink(s1))); HashFilter hf(hmac, new HexEncoder(new StringSink(s2))); // Encrypt and authenticate message ChannelSwitch cs; cs.AddDefaultRoute(ef); cs.AddDefaultRoute(hf); StringSource ss(message, true /*pumpAll*/, new Redirector(cs)); // Print stuff cout << "Message: " << message << endl; cout << "MAC of Message: " << s2 << endl; cout << "Cipher text: " << s1 << endl;
A typical run is shown below.
$ ./cryptopp-test.exe Encryption key: 00000000000000000000000000000000 Encryption iv: 00000000000000000000000000000000 HMAC key: 00000000000000000000000000000000 Message: Now is the time for all good men to come to the aide of their country MAC of Message: E1396F07CE04D528152443C773E4A20F51AA1AB007F859943225D8F500EAF057 Ciphertext: 7FF8B3EA8A02B37A3D28669C9713A7B30FA2502580D5D232CEE80A5733EF70FF48E9 E80498A904C25EA7B04043A1FC238B03AA06EC90498478FB29013EE7DE6B9E37B03B F7FA2609CE7E48B460BE36AA
Sample
ChannelSwitch.zip - Demonstrates using the ChannelSwitch class to digest a string using multiple hashes - 7.9 kB