Speichern der IV mit dem verschlüsselten Text Crypto ++ CBC-AES-Verschlüsselung
Einige der Code, den Sie verwenden, ist ein bisschen zu mir ungewöhnlich. Ich wähle ein paar Dinge aus und zeige dir einige der Möglichkeiten von Crypto ++.
Bevor Sie beginnen, werfen Sie einen Blick auf Pipelines und Pumping Data auf dem Crypto ++ Wiki. Denken Sie daran, dass Daten von Quellen zu Senken fließen. Dazwischen treffen die Daten auf Filter, die die Daten transformieren.
std::ifstream fin(file_path, std::ios::binary);
if (!fin)
{
std::cout << "error";
}
std::ostringstream ostrm;
ostrm << fin.rdbuf();
std::string plaintext(ostrm.str());
fin.close();
A Crypto ++ FileSource
hat einen Konstruktor, der ein std::istream
dauert. Sie könnten etwas wie das Folgende tun. Siehe auch FileSource
im Crypto ++ Wiki.
std::ifstream fin(file_path, std::ios::binary);
FileSource source(fin, true /*pump all*/, NULLPTR);
...
AES::Encryption aesEncryption(key, CryptoPP::AES::MAX_KEYLENGTH);
CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);
ExternalCipher
sind für die FIPS-DLL. Sie können sie ohne die DLL verwenden, aber sie existieren für die DLL. Normalerweise verwenden Sie:
CBC_Mode<AES>::Encryption encryptor;
Auch Sie in der Regel vermeiden wollen eine Vertraulichkeit-only Modus. Normalerweise möchten Sie eine Authenticated Encryption Betriebsart verwenden. Es bietet Vertraulichkeit und Authentizität.
Crypto ++ bietet CCM, EAX und GCM authentifizierte Verschlüsselungsmodi. OCB und EAX sind eine sehr gute Wahl. Der EAX-Modus ist unter EAX Mode im Crypto ++ Wiki dokumentiert. OCB ist im Moment nicht verfügbar. Wir bereiten uns auf den OCB-Modus vor.
Nun, ich möchte den verschlüsselten String in eine Datei schreiben, und speichern Sie die IV mit ihm, da der iv muss nicht geheim gehalten werden, idealerweise am Anfang oder am Ende der Chiffretext
Verwenden Sie etwas wie folgt. Ich habe es nicht kompiliert, also müssen Sie die Tippfehler beheben.
AutoSeededRandomPool prng;
SecByteBlock key(AES::MAXIMUM_KEYLENGTH), iv(AES::BLOCKSIZE);
RandomNumberSource rs1(prng, AES::MAXIMUM_KEYLENGTH, new ArraySink(key, key.size()));
RandomNumberSource rs2(prng, AES::BLOCKSIZE, new ArraySink(iv, iv.size()));
HexEncoder encoder(new FileSink(std::cout));
std::cout << "Key: ";
encoder.Put(key, key.size());
encoder.MessageEnd();
std::cout << std::endl;
std::cout << "IV: ";
encoder.Put(iv, iv.size());
encoder.MessageEnd();
std::cout << std::endl;
EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key, key.size(), iv, iv.size());
// Plaintext message
std::string message;
// Output file
FileSink file("message.enc");
// Source wrappers
ArraySource as(iv, iv.size(), true,
new Redirector(file));
// Source wrapper
StringSource ss(message, true,
new StreamTransformationFilter(encryptor,
new Redirector(file)));
Wenn ich werde versuchen, diese Datei zu entschlüsseln, wie kann ich extrahieren Sie die iv und Chiffretext getrennt?
Verwenden Sie etwas wie folgt.
// Key is from previous example. It cannot change
SecByteBlock key(AES::MAXIMUM_KEYLENGTH), iv(AES::BLOCKSIZE);
FileSource fs("message.enc", false /* DO NOT Pump All */);
// Attach new filter
ArraySink as(iv, iv.size());
fs.Attach(new Redirector(as));
fs.Pump(AES::BLOCKSIZE); // Pump first 16 bytes
EAX<AES>::Decryption decryptor;
decryptor.SetKeyWithIV(key, key.size(), iv, iv.size());
// Detach previously attached filter, attach new filter
ByteQueue queue;
fs.Detach(new StreamTransformationFilter(decryptor, new Redirector(queue)));
fs.PumpAll(); // Pump remainder of bytes
Die verschlüsselten Daten werden in einem ByteQueue
sein. Es ist nicht bieten C++ Iterator-ähnliche Funktionalität, wie ein Zeiger und eine Größe. Um die Daten zu erhalten, aus dem ByteQueue
Sie es übertragen oder kopieren Sie sie in einem anderen Filter oder ein Waschbecken:
SecByteBlock block(queue.MaxRetrievable());
ArraySink sink(block, block.size());
queue.TransferTo(sink);
Sie können die Daten erhalten aus dem ByteQueue
und steckte es in eine std::string
mit:
std::string recovered;
StringSink sink(recovered);
queue.TransferTo(sink);
Und Sie können die IV aus der Datei wiederhergestellt drucken mit:
HexEncoder encoder(new FileSink(std::cout));
std::cout << "IV: ";
encoder.Put(iv, iv.size());
encoder.MessageEnd();
std::cout << std::endl;
gibt es keine vorgefertigten primitiv, dass in diesem lib für Sie tun? Nein? Dann seien Sie vorsichtig und lesen Sie sich die base64-Codierung durch. – sascha
Ich habe nichts im wiki gesehen, das zu tun. Ich kann das iv (das ein Byte [] ist) zu einem String kodieren, aber der Dekodierungsprozess ist komplizierter, da er den kodierten String in einen decodierten String konvertiert, und ich möchte meine Byte-Array wiederherstellen :) – EinderJam