"неизвестно: этот объект не поддерживает несколько каналов" во время шифрования

Я получаю исключение "неизвестно: этот объект не поддерживает несколько каналов" во время шифрования файла. Я могу создать ключ сеанса, но его нельзя использовать для шифрования файла.

Вот мой фрагмент кода для шифрования файлов:

void enc_file_EAX(PAES_KEY_WITH_IV key, const char *in_file, const char *out_file)
{

    try {
        CryptoPP::EAX<CryptoPP::AES>::Encryption encryptor;
        encryptor.SetKeyWithIV(key->key, key->key.size(), key->iv);
        CryptoPP::FileSource f(in_file, true,
                     new CryptoPP::AuthenticatedEncryptionFilter(encryptor,
                        new CryptoPP::FileSink(
                             std::string(in_file).c_str()),
                             CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION |
                             CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END ));
        std::fstream file(out_file, std::ios::binary | std::ios::ate);
        size_t remaining = file.tellg();
        file.close();
        size_t BLOCK_SIZE = 16384;
        while (remaining && !f.SourceExhausted()) {
            const unsigned int req = std::min(remaining, BLOCK_SIZE);
            f.Pump(req);
            f.Flush(false);
            remaining -= req;
        }

    } catch (const CryptoPP::Exception& e) {
        std::cout << e.GetWhat() << std::endl;
        return;
    }
}

Может ли кто-нибудь помочь мне в этом? Что здесь не так?

Заранее спасибо.

1 ответ

Решение
EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key->key, key->key.size(), key->iv);
FileSource f(in_file, true,
        new AuthenticatedEncryptionFilter(encryptor,
            new FileSink(
                std::string(in_file).c_str()),
            AuthenticatedDecryptionFilter::THROW_EXCEPTION |
            AuthenticatedDecryptionFilter::MAC_AT_END ));

Вы смешиваете и сопоставляете механизмы шифрования и дешифрования в одном и том же объектном конвейере. Возможно, вам следует исправить это в первую очередь.

Глядя на http://www.cryptopp.com/wiki/AuthenticatedEncryptionFilter, THROW_EXCEPTION | MAC_AT_END флаги, вероятно, принуждают в putAAD флаг:

AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c,
    BufferedTransformation *attachment = NULL, bool putAAD=false,
    int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL,
    BlockPaddingScheme padding=DEFAULT_PADDING);

Кажется, я помню, что вам нужно избегать конвейеров, если вы хотите добавить AAD. Канал позволяет вводить данные только на DEFAULT_CHANNEL, который обеспечивает AE (но не AAD). Также см. EAX Mode | Пример AEAD на вики Crypto++.


Ваше использование FileSink а также FileSource выглядит не совсем правильно. Я не уверен, как это будет себя вести

FileSource f(in_file, true, ...
    new FileSink(std::string(in_file).c_str()), ...);

Вы, вероятно, должны использовать in_file.c_str() для имени файла:

FileSource f(in_file.c_str(), ...);

Вы также, вероятно, должны использовать другой файл для раковины:

FileSource f(out_file.c_str(), ...);

РЕДАКТИРОВАТЬ (из комментариев):

Нет, мы не хотим добавлять конвейер, мы просто хотим использовать DEFAULT_CHANNEL для ввода данных. И данный пример для ввода текста. Я хочу использовать ту же функцию для ввода файлов. Можете ли вы подробнее рассказать об этом?

В этом случае попробуйте:

EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key->key, key->key.size(), key->iv);
FileSource f(in_file.c_str(), true,
        new AuthenticatedEncryptionFilter(encryptor,
            new FileSink(out_file.c_str()));

Это должно вводить текст для конфиденциальности и целостности (AE). Это позволит избежать текста только с конфиденциальностью (AEAD).

Также смотрите EAX Mode на Crypto++ wiki. Он имеет три или четыре примера с AE и AEAD.

Другие вопросы по тегам