密码术 - 发布模式下的Bizzare行为

时间:2016-08-31 14:09:56

标签: c++ cryptography release undefined-behavior crypto++

我使用Crypto++创建了一个项目。

Crypto ++是一个自己的项目,它构建在静态库中 除此之外,我还有另一个使用一些Crypto ++类并处理各种算法的大型项目,这些算法也构建在静态库中。

其中两个功能是:

long long MyClass::EncryptMemory(std::vector<byte> &inOut, char *cPadding, int rounds)
{
    typedef std::numeric_limits<char> CharNumLimit;
    char sPadding = 0;
    //Calculates padding and returns value as provided type
    sPadding = CalcPad<decltype(sPadding)>(reinterpret_cast<MyClassBase*>(m_P)->BLOCKSIZE, static_cast<int>(inOut.size()));
    //Push random chars as padding, we never care about padding's content so it doesn't matter what the padding is
    for (auto i = 0; i < sPadding; ++i)
        inOut.push_back(sRandom(CharNumLimit::min(), CharNumLimit::max()));
    std::size_t nSize = inOut.size();
    EncryptAdvanced(inOut.data(), nSize, rounds);
    if (cPadding)
        *cPadding = sPadding;
    return nSize;
}

//Removing the padding is the responsibility of the caller.
//Nevertheless the string is encrypted with padding
//and should here be the right string with a little padding
long long MyClass::DecryptMemory(std::vector<byte> &inOut, int rounds)
{
    DecryptAdvanced(inOut.data(), inOut.size(), rounds);
    return inOut.size();
}

EncryptAdvancedDecryptAdvanced将参数传递给Crypto ++对象。

//...
AdvancedProcessBlocks(bytePtr, nullptr, bytePtr, length, 0);
//...

到目前为止,这些功能完美无缺,几个月来一直没有对它们进行任何修改。 围绕它们的逻辑已经发展,尽管传递给它们的调用和数据没有改变。

加密/解密的数据相当小但有动态大小,正在填充if (datasize % BLOCKSIZE)有余数。
示例:AES Blocksize为16.数据为31.填充为1.数据现为32。

在加密之后和解密之前,字符串是相同的 - 如图中所示。

Encrypt/Decrypt data

调试模式中运行所有这些显然按预期工作。即使在另一台计算机上运行此程序(为DLL安装了VS),它也没有任何区别。数据已正确加密和解​​密。

尝试在发布模式下运行相同的代码会导致完全不同的加密字符串,加上它无法正确解密 - “垃圾数据”会被解密。错误加密或解密的数据是一致的 - 始终将相同的垃圾解密。密钥/密码和轮次/迭代始终是相同的

附加信息:数据保存在文件(ios_base::binary)中,并在调试模式下使用相同的静态库(y / ies)从同一解决方案中的两个不同程序正确处理。

这个调试/发布问题可能是什么原因?

我重新检查了git历史记录几次,通过代码调试了几天,但我找不到任何可能导致此问题的原因。如果有任何信息 - 除了(这里相当不可能)MCVE是必需的,请发表评论。

1 个答案:

答案 0 :(得分:0)

显然这是CryptoPP中的一个错误。 Rijndael / AES的最小密钥长度设置为8而不是16.使用8字节的无效密钥长度将导致对Rcon值的就地数组的越界访问。此密钥长度为8字节,目前报告为有效,必须在CryptoPP中修复。

有关详细信息,请参阅this issue on github。 (正在进行的对话)