c++ - 使用 AuthenticatedEncryptionFilter 时没有错误

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

我的问题是,无论使用什么输入,该方法在解密时都不会抛出错误。我可以修改加密文件或使用其他密码或其他什么,我只会得到一个错误解密的文件,但也不异常(exception)。

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

为什么没有抛出任何异常?

最佳答案

My Problem is, that this Method is not throwing an Error when decrypting no matter what inputs are used. I can modify the encrypted file or use another password or whatever, I only get an incorrectly decrypted file, but no exception...

Why is not throwing any exception?

缺点是, FileSource file(url.c_str(), false, new AuthenticatedDecryptionFilter...) 表示该消息不是 Put因为 pumpAll=false 。因为消息不是Put , LastPut ,触发MAC验证,没有被调用。您可以使用 MessageEnd 触发它,但你还没有读完消息,所以总是会失败。

我明白你想要做什么,而且解决方法比较棘手。


从大局来看,几乎一切都很好。在使用数据之前,您正在使用经过身份验证的加密和 MAC'ing。但我想知道单一或“一次”MAC 是否是解决该问题的方法。

要在这种情况下使用单个 MAC,您可能希望从验证中删除解密。您仍然想要执行这些操作,但是您希望将它们作为单独的步骤执行。在解密之前,您将验证整个消息的 MAC(只读操作,快速)。一旦MAC验证通过,就可以进行解密(读写操作,速度慢)。不幸的是,该库不提供单独的 EAX_Mac 您可以键入的类,使用消息,然后确定 MAC 是否良好。

也许可行的方法是在每个 block 大小的数据单元上应用 MAC,例如 4096 或 16384。这是 Bernstein 在 CAESAR Competition 中设想的用例或处理方式。 。竞赛的目的是下一代经过身份验证的加密方案。不幸的是,该库没有设置过滤器来执行此操作。


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

创建 BlockedAuthenticatedEncryptionFilter 。而不是加密器对象的 key :

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

现在,BlockedAuthenticatedEncryptionFilter将积累源数据。每当一个完整的 block 可用时,它就会在 key 和 iv 下对该 block 执行经过身份验证的加密。这是安全上下文下的加密 ( {message,key,iv} ),因此必须为下一个 block 或消息更改安全上下文。这就是为什么过滤器是关键的而不是模式的原因。

更改安全上下文 {message,key,iv} 对于下一条消息,您可以执行简单的 Increment在 key 和 iv 上。这将确保每条消息的安全上下文都是唯一的。

不能做的一件事就是调用encryptor.GetNextIV()获得从密码状态导出的下一个确定性 iv。这是因为,根据设计,图书馆不提供它。这有时会出现在邮件列表中,但目前我找不到示例消息。

但是,不知道有什么麻烦next_key = Increment(key)next_iv = Increment(iv)可能会导致,所以我需要考虑一下并进行一些研究。我可能会在 Security Stack Exchange 上询问。或Cryptography Stack Exchange ,也是。

关于c++ - 使用 AuthenticatedEncryptionFilter 时没有错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35464554/

相关文章:

php - 如何为多个用户存储加密文件

c++ - 将 C++ builder 6 项目转换为 C++ builder 2010

java - 将 Java 加密算法移植到 C++ OpenSSL

c++ - 函数 sqlite3_open_v2 文件路径

c++ - 将整数数据类型值添加到指针而不是 double 值

C++,VS2010 : Avoid downloading MS redistrubutable package. 静态链接?

c++ - 使用 Linux 命令行 g++ 构建 Crypto++ 5.6.5 问题

c++ - xCode 编译旧的 C++ 代码

c++ - Eclipse 中的 Crypto++ 未定义引用

c++ - 这个 sha 256 函数有什么问题?