C++ 使用AuthenticatedEncryptionFilter时没有错误
我使用Crypto++对文件进行加密和解密,代码如下:C++ 使用AuthenticatedEncryptionFilter时没有错误,c++,encryption,crypto++,C++,Encryption,Crypto++,我使用Crypto++对文件进行加密和解密,代码如下: try { EAX<AES>::Encryption encryptor; encryptor.SetKeyWithIV(derived.data(), 32, ivb, ivb.size()); FileSource f(fileUrl.c_str(), false, new AuthenticatedEncryptionFilter(encryptor, new F
try {
EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(derived.data(), 32, ivb, ivb.size());
FileSource f(fileUrl.c_str(), false,
new AuthenticatedEncryptionFilter(encryptor, new FileSink(
std::string(fileUrl).c_str()), CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION | CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END ));
std::fstream file(fileUrl, 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 = STDMIN(remaining, BLOCK_SIZE);
f.Pump(req);
f.Flush(false);
remaining -= req;
}
} catch (const CryptoPP::Exception& e) {
cout << e.GetWhat();
return 5;
}
试试看{
EAX::加密机;
encryptor.SetKeyWithIV(派生的.data(),32,ivb,ivb.size());
FileSource f(fileUrl.c_str(),false,
新的AuthenticatedEncryptionFilter(加密程序、新文件链接(
std::string(fileUrl.c_str()),CryptoPP::AuthenticatedDecryptionFilter::THROW_EXCEPTION | CryptoPP::AuthenticatedDecryptionFilter::MAC_AT_END));
std::fstream文件(fileUrl,std::ios::binary | std::ios::ate);
剩余大小=file.tellg();
file.close();
块大小=16384;
while(剩余的&!f.sourcedefined()){
const unsigned int req=STDMIN(剩余,块大小);
f、 泵(req);
f、 齐平(假);
剩余-=req;
}
}catch(const CryptoPP::Exception&e){
库特
我的问题是,无论使用什么输入,此方法在解密时都不会引发错误。我可以修改加密文件或使用其他密码或其他任何方式,我只会得到一个解密错误的文件,但没有例外…
为什么不抛出任何异常
它的缩写是,文件源文件(url.c_str(),false,newauthenticatedDecryptionFilter…)
表示消息是非放
,因为pumpAll=false
。因为消息不是放
,所以不会调用触发MAC验证的最后放
。您可以使用消息结束
触发它,但您不在消息的结尾,所以总是会失败
我明白你想做什么,解决办法更棘手
从总体上看,几乎一切都正常。在使用数据之前,您使用的是经过身份验证的加密和MAC。但我想知道,单一或“一次性”MAC是解决问题的方法
在这种情况下,若要使用单个MAC,您可能希望从验证中排除解密。您仍然希望进行解密,但希望将其作为单独的步骤进行。在解密之前,您将在整个消息上验证MAC(只读操作,快速)。MAC验证后,您将执行解密(读写操作,慢速)。遗憾的是,该库不提供单独的EAX\u Mac
类,您可以键入、使用消息,然后确定Mac是否正常
也许应该在每个块大小的数据单元(如4096或16384)上应用MAC。这是Bernstein等人在中设想的使用案例或处理。竞争对手是下一代经过身份验证的加密方案。不幸的是,该库没有过滤器集来完成这项工作
通过自定义过滤器在块大小的数据单元上应用MAC是可能的,这在安全工程中是一个有趣的问题,因为每个安全上下文必须是唯一的
创建一个BlockedAuthenticatedEncryptionFilter
。而不是为encryptor对象设置密钥:
EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(derived.data(), derived.size(), iv, iv.size());
现在,blockedAuthenticateEncryptionFilter
将累积源数据。只要有完整的块可用,它就会在密钥和iv下对块执行经过身份验证的加密。这是安全上下文下的加密({message,key,iv}
),因此,必须为下一个块或消息更改安全上下文。这就是为什么过滤器是键控的,而不是模式
要更改下一条消息的安全上下文{message,key,iv}
,您可以在key和iv上执行一个简单的增量
。这将确保每个消息的安全上下文都是唯一的
不能做的一件事是调用encryptor.GetNextIV()
以获取从密码状态派生的下一个确定性iv。这是因为,根据设计,库不提供它。这有时会出现在邮件列表中,但我目前找不到示例消息
但是,我不确定有什么问题next\u key=Increment(key)
和next\u iv=Increment(iv)
可能会导致,所以我需要考虑一下并研究一下。我可能也会在或上询问它。我就这个用例联系了Crypto++库的作者。他现在忙于其他事情,所以他没有多余的周期来处理这些问题。但他仍然可以回答问题对我们来说是个问题。一旦我们得到了大致的方向,我希望我们能为您的问题找到一个解决方案。我希望它像一个新的标志一样简单,可能是验证\u MAC
,它在不解密的情况下执行MAC验证。可能是忽略\u MAC
,它只允许您在验证MAC后解密。
EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(derived.data(), derived.size(), iv, iv.size());
FileSource f(... new BlockedAuthenticatedEncryptionFilter(
encryptor,
key.data(), key.size(),
iv, iv.size(),
new FileSink(...));