使用AuthenticatedEncryptionFilter时没有错误

时间:2016-02-17 18:16:26

标签: 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 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;
}

解密:

try {

    EAX<AES>::Decryption decryptor;
    decryptor.SetKeyWithIV(derived2.data(), 32, ivb2, ivb2.size());

    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 ));

    file.open(fileUrl, std::ios::binary | std::ios::ate);
    size_t remaining = file.tellg();
    remaining -= 3;
    file.close();

    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;
    }
} catch (const CryptoPP::Exception& e) {
    cout << e.GetWhat();
    return 5;
}

我的问题是,无论使用什么输入,此方法在解密时都不会抛出错误。我可以修改加密文件或使用其他密码或其他任何密码,我只能获得错误解密的文件,但也不例外。

据我所知,AuthenticatedDecryptionFilter应自动检查这些内容并抛出异常。

为什么不抛出任何异常?

1 个答案:

答案 0 :(得分:2)

  

我的问题是,无论使用什么输入,此方法在解密时都不会抛出错误。我可以修改加密文件或使用其他密码或其他什么,我只得到一个错误解密的文件,但没有例外...
  
  为什么不抛出任何异常?

缺点是, FileSource file(url.c_str(), false, new AuthenticatedDecryptionFilter...) 表示邮件 {{1因为 Put 。由于消息不是pumpAll=false,因此不会调用触发MAC验证的 Put 。您可以使用 LastPut 触发它,但您不在信息的末尾,因此总是会失败。

我明白你要做的是什么,修复更棘手。

总体而言,几乎一切都还可以。在使用数据之前,您使用的是经过身份验证的加密和MAC。但是我想知道单身或者是一次拍摄&#34; MAC是解决问题的方法。

要在这种情况下使用单个MAC,您可能希望从验证中解除解密。您仍然希望这样做,但您希望将它们作为单独的步骤来执行。在解密之前,您将在整个消息上验证MAC(只读操作,快速)。 MAC验证后,然后执行解密(读写操作,慢速)。不幸的是,该库没有提供单独的 MessageEnd 类,您可以键入,使用该消息,然后确定MAC是否正常。

可能的方法是在每个块大小的数据单元上应用MAC,如4096或16384.这是Bernstein等人在CAESAR Competition中设想的用例或处理。该竞赛适用于下一代经过身份验证的加密方案。不幸的是,该库没有设置过滤器。

通过自定义过滤器在块大小的数据单元上应用MAC是可能的,并且它在安全工程中是一个有趣的问题,因为每个安全上下文必须是唯一的。我认为接近它的方法是......

创建EAX_Mac。而不是键入加密器对象:

BlockedAuthenticatedEncryptionFilter

键入EAX<AES>::Encryption encryptor; encryptor.SetKeyWithIV(derived.data(), derived.size(), iv, iv.size()); 代替:

BlockedAuthenticatedEncryptionFilter

现在,FileSource f(... new BlockedAuthenticatedEncryptionFilter( encryptor, key.data(), key.size(), iv, iv.size(), new FileSink(...)); 将累积源数据。只要有完整块,它就会在密钥和iv下的块上执行经过身份验证的加密。这是安全上下文( BlockedAuthenticatedEncryptionFilter )下的加密,因此必须针对下一个块或消息更改安全上下文。这就是为什么过滤器是键控的而不是模式。

要为下一封邮件更改安全上下文 {message,key,iv} ,您可以在密钥和密钥上执行简单的{message,key,iv} IV。这将确保每条消息的安全上下文都是唯一的。

无法 做的一件事就是致电Increment以获取从密码中获取的下一个确定性 iv #39; s州。这是因为,按照设计,图书馆不提供它。这有时会出现在邮件列表中,但我目前无法找到示例消息。

但是,我不确定encryptor.GetNextIV()next_key = Increment(key)会导致什么问题,所以我需要考虑一下并对其进行一些研究。我可能会在Security Stack ExchangeCryptography Stack Exchange上询问它。