Объединить IV и данные в строке Base64 с помощью Crypto ++? - PullRequest
2 голосов
/ 16 октября 2019

Мне нужно было зашифровать строку в 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 ++и конвейерная парадигма, я чувствую, что, возможно, я сделал слишком много шагов, чтобы достичь того, чего я хочу.

Есть ли более краткий или более эффективный способ сделать это?

...