Мне нужно было зашифровать строку в AES / CBC. Чтобы потом можно было его расшифровать, я должен сохранить IV в конечном результате, который должен быть строкой base64.
Мне удается сделать это, используя этот answer и образцы Crypto ++. :
std::string String::AESEncryptString(std::string str, std::string key)
{
std::string encoded;
std::string b64Result = "";
AutoSeededRandomPool prng;
unsigned char iv[AES::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
StringSink output(encoded);
// Put the IV at the begining of the output
StringSource(iv, sizeof(iv), true,
new Redirector(output)
);
try {
CBC_Mode<AES>::Encryption encryptor((unsigned char *)key.c_str(), key.length(), iv);
StringSource s(str, true,
new StreamTransformationFilter(encryptor,
new Redirector(output), StreamTransformationFilter::PKCS_PADDING
)
);
// Convert to b64
StringSource (encoded, true,
new Base64Encoder(
new StringSink(b64Result),
false // do not append a newline
)
);
return b64Result;
} catch (const Exception& e) {
return "";
}
}
Чтобы расшифровать строку base64, я сначала извлекаю IV, а затем расшифровываю остальные данные:
std::string String::AESDecryptString(std::string str, std::string key)
{
unsigned char iv[AES::BLOCKSIZE];
std::string b64decoded;
std::string decoded;
try {
StringSource(str, true,
new Base64Decoder(
new StringSink(b64decoded)
)
);
StringSource ss(b64decoded, false);
// Get the IV
ArraySink ivSink(iv, sizeof(iv));
ss.Attach(new Redirector(ivSink));
ss.Pump(AES::BLOCKSIZE);
CBC_Mode<AES>::Decryption decryptor((unsigned char *)key.c_str(), key.length(), iv);
ByteQueue queue;
ss.Detach(
new StreamTransformationFilter(decryptor,
new Redirector(queue)
)
);
ss.PumpAll(); // Pump remainder bytes
StringSink decodedSink(decoded);
queue.TransferTo(decodedSink);
return decoded;
}
catch (const Exception& e) {
return "";
}
}
Все работает нормально, но, как только я открываю Crypto ++и конвейерная парадигма, я чувствую, что, возможно, я сделал слишком много шагов, чтобы достичь того, чего я хочу.
Есть ли более краткий или более эффективный способ сделать это?