【发布时间】:2019-04-11 11:27:06
【问题描述】:
我正在使用 CryptoPP 库来散列一些密码。大约 10 次中有 1 次在下面的 DeriveKey 行上崩溃,并出现段错误。
即使使用固定参数,崩溃似乎仍然是随机的。我想知道我的字符串末尾是否需要一个 '\0' 。或者输出缓冲区可能需要零初始化,或者什么?
无论如何,这是代码。
#include <cryptopp/aes.h>
#include <cryptopp/algparam.h>
#include <cryptopp/filters.h>
#include <cryptopp/modes.h>
#include <cryptopp/sha.h>
#include <cryptopp/pwdbased.h>
int main()
{
CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256> pbkdf2;
CryptoPP::byte salt[16];
CryptoPP::byte key[32];
/* Hard coded for testing purposes */
Common::podFromHex("00f8807a289655b2a8e38cda00182a32", salt);
/* Hard coded for testing purposes */
std::string password = "a";
std::cout << "Salt: " << Common::podToHex(salt) << std::endl;
std::cout << "Salt size: " << sizeof(salt) << std::endl;
std::cout << "Password: " << password.data() << std::endl;
std::cout << "Password size: " << password.size() << std::endl;
/* Rare segfault on this line */
pbkdf2.DeriveKey(
key, sizeof(key), 0, (CryptoPP::byte *)password.data(),
password.size(), salt, sizeof(salt), Constants::PBKDF2_ITERATIONS
);
}
一切似乎都已正确初始化 - 打印语句每次都给我完全相同的东西:
Salt: 00f8807a289655b2a8e38cda00182a32
Salt size: 16
Password: a
Password size: 1
此外 - 哈希密码在没有段错误时是可用的。后面我用AES加密,可以完美解密文件,所有数据都符合预期。
派生密钥的源代码可以在这里找到,顺便说一句:https://www.cryptopp.com/docs/ref/pwdbased_8h_source.html#l00235
谢谢。
【问题讨论】:
-
我们需要更多信息,比如公共库的相关源代码。带有堆栈跟踪的确切崩溃行也会有所帮助。您可能应该在 Valgrind 或其他内存检查工具(如 Address Sanitizer)下运行您的程序。
-
我正在考虑使用 valgrind 运行 - 这有点痛苦,因为我使用的一些周围代码会抛出大量错误 - 我可能应该在单独的程序中测试它。我将摆脱通用库以获得更好的最小示例 - 我相当确定代码的那部分没有问题,它只是转换为十六进制。
-
你应该在
-O1保持 Valgrind-clean。如果您在-O1观察到大量 Valgrind 的发现,那么您可能有一些问题需要解决。另见The Valgrind Quick Start Guide | Preparing your program。 (-O2和-O3的 {Some|Many} 发现是误报)。 -
哦,当然,当前代码库存在大量问题 - 尝试慢慢修复它们。