Filtre Crypto ++ "Tee"

Je travaille sur le traitement d'un flux de données en fonction de certaines conditions.

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

Maintenant, je voudrais "snoop" sur les données circulant entre le cryptage et le magasin de fichiers, en calculant une somme de contrôle. Pour des raisons de performance, je veux le faire en streaming, en rouvrant le fichier de sortie et en calculant une somme de hachage après n'est pas raisonnable pour mon besoin.

D'après ce que je peux voir, ce qui manque pour que cela fonctionne, c'est une forme de filtre "tee". Quelque chose divise la chaîne de données en deux nouvelles chaînes, une pour le stockage dans le fichier et une pour le calcul du hachage.

Y a-t-il une telle fonctionnalité dans Crypto ++? Puis-je implémenter un tel filtre moi-même, et si oui, existe-t-il des lignes directrices ou des exemples sur ce qui est nécessaire pour un filtre Crypto ++ personnalisé? Existe-t-il un autre moyen de calculer la somme de contrôle à la volée?

0
Merci pour le conseil. Toutefois, AFAICT, il ne prend pas en charge à la fois la génération d'une signature et la transmission de données en continu, n'est-ce pas?
ajouté l'auteur Rawler, source
Cela semble très similaire à ce que fait SignerFilter , implémenté dans filter.cpp .
ajouté l'auteur Christopher Creutzig, source
Je crois que c'est le cas lorsque vous définissez le dernier paramètre du constructeur sur true . De la même manière, je pense que SignatureVerificationFilter , si on lui donne PUT_MESSAGE dans ses drapeaux, dans des fonctions comme NextPutMultiple , transmet le message à un filtre supplémentaire, en plus de mettre à jour son hachage. Mais je n'ai pas écrit de code pour tester ça.
ajouté l'auteur Christopher Creutzig, source

1 Réponses

D'après ce que je peux voir, ce qui manque pour que cela fonctionne, c'est une forme de filtre "tee".   ...   Y a-t-il une telle fonctionnalité dans Crypto ++?

Oui, cela s'appelle un ChannelSwitch . Ce qui suit est de la page wiki de Crypto ++ sur ChannelSwitch , et il suit l'utilisation de Wei Dai de la classe dans ses fichiers de test.

MD5 hashMD5;
HashFilter filterMD5(hashMD5);

SHA1 hashSHA1;
HashFilter filterSHA1(hashSHA1);

std::auto_ptr 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();

Voici la sortie de l'exemple ci-dessus:

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

Voici un autre exemple qui utilise des puits distincts et pourrait être plus facile à suivre:

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;

Voici la sortie de l'exemple:

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