Исключение Crypto++, вызывающее messageEnd

Я использую следующий код для расшифровки файла:

FileSource fe(fileUrl.c_str(), false,
                  new AuthenticatedDecryptionFilter(decryptor, new FileSink(
                          std::string(fileUrl).c_str()), CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION |  CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END ));

        size_t BLOCK_SIZE = 16384;
    while (remaining && !fe.SourceExhausted()) {
        const unsigned int req = STDMIN(remaining, BLOCK_SIZE);
        fe.Pump(req);
        fe.Flush(false);

        remaining -= req;
    }
    fe.MessageEnd();

Если я попытаюсь сделать это без fe.MessageEnd(), мой расшифрованный файл будет короче на 16 байт. Поэтому я подумал, что мне нужно вызвать MessageEnd(), чтобы решить эту проблему. Но если я вызываю MessageEnd(), я получаю следующее исключение: BufferedTransformation: этот объект не разрешает ввод


person Ben    schedule 01.03.2016    source источник


Ответы (1)


если я вызываю MessageEnd(), я получаю следующее исключение: BufferedTransformation: this object doesn't allow input...

Правильный. FileSource является источником, и сообщение должно существовать. Вы не можете вызвать Put или Put2 для источника, чтобы добавить дополнительные данные в сообщение.


Я думаю, у вас есть два варианта, чтобы лучше контролировать сигналы.

Первый

Позвоните Flush по телефону Source.

const int opts = AuthenticatedDecryptionFilter::THROW_EXCEPTION |
    AuthenticatedDecryptionFilter::MAC_AT_END;

FileSource fe(fileUrl.c_str(), false,
    new AuthenticatedDecryptionFilter(decryptor, new FileSink(
        std::string(fileUrl).c_str()), opts));

fe.Flush(true);

Также см. комментарии для Flush по адресу Filter::Flush в руководстве.

Второй

Спрячьте указатель на фильтр и вызовите для него MessageEnd.

const int opts = AuthenticatedDecryptionFilter::THROW_EXCEPTION |
     AuthenticatedDecryptionFilter::MAC_AT_END;
AuthenticatedDecryptionFilter* adf = NULL;

FileSource fe(fileUrl.c_str(), false,
    adf = new AuthenticatedDecryptionFilter(decryptor, new FileSink(
        std::string(fileUrl).c_str()), opts));
adf.MessageEnd();

Это довольно необычно, поэтому я не уверен, с какими побочными эффектами вы столкнетесь.

Не удаляйте указатель. FileSource удалит его, когда он выйдет за пределы области действия закрывающей скобки.


... мой расшифрованный файл короче на 16 байт...

На мой взгляд, это проблема, которую вы должны решить, если вызов Flush на Source не работает для вас.

Также имейте в виду... Результатом AuthenticatedEncryptionFilter является 2-кортеж {ciphertext,mac}, поэтому вы получаете зашифрованный текст расширение 16-байт из-за MAC. Позже, когда вы используете AuthenticatedDecryptionFilter, mac удаляется после его проверки. Таким образом, восстановленный текст должен быть того же размера, что и обычный текст, оба из которых должны быть на 16 байт меньше, чем зашифрованный текст.

Что мне не ясно, так это то, что все работает так, как ожидалось, но вы не понимаете, как это должно работать. Или вы действительно где-то теряете 16 байт восстановленного текста.

person jww    schedule 02.03.2016
comment
Я теряю 16 байт открытого текста в конце. Я рассмотрю ваши варианты позже. - person Ben; 02.03.2016
comment
Спасибо за ваш ответ, ваш первый вариант с использованием fe.Flush(true) работает нормально. - person Ben; 03.03.2016