"неизвестно: этот объект не поддерживает несколько каналов" во время шифрования
Я получаю исключение "неизвестно: этот объект не поддерживает несколько каналов" во время шифрования файла. Я могу создать ключ сеанса, но его нельзя использовать для шифрования файла.
Вот мой фрагмент кода для шифрования файлов:
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.