c++ - 使用 Crypto++ 比较恒定时间密码摘要

标签 c++ hash crypto++ pbkdf2

我正在编写一个程序,用 pbkdf2 method using cryptopp 散列密码.

我在验证密码时遇到问题。我试图比较“长度常数”时间的输出,但它总是失败并返回 false。

// a and b are std strings containing the output of the DeriveKey function

unsigned diff = a.length() ^ b.length();
for(unsigned i = 0; i < a.length() && i < b.length(); i++)
{
      diff |= (unsigned)a[i] ^ (unsigned)b[i];
}

bool equal = diff == 0;

使用“slow equals”甚至是验证 pbkdf2 密码的正确方法吗?我对此有点困惑。

最佳答案

I'm writing a program which hashes passwords with the pbkdf2 method using cryptopp.

您链接到 Crypto++ 主页,而不是您对 PBKDF 的特定使用。这是 some code以防万一(它使用来自 RFC 6070 的 IETF 测试 vector ):

int main(int argc, char* argv[])
{
    byte password[] ="password";
    size_t plen = strlen((const char*)password);

    byte salt[] = "salt";
    size_t slen = strlen((const char*)salt);

    int c = 1;
    byte derived[20];

    PKCS5_PBKDF2_HMAC<CryptoPP::SHA1> pbkdf2;
    pbkdf2.DeriveKey(derived, sizeof(derived), 0, password, plen, salt, slen, c);

    string result;
    HexEncoder encoder(new StringSink(result));

    encoder.Put(derived, sizeof(derived));
    encoder.MessageEnd();

    cout << "Derived: " << result << endl;

    return 0;
}

I have tried to compare the output in "length-constant" time but it always fails and returns false.

Crypto++ 具有内置的恒定时间比较。使用来自 misc.hVerifyBufsEqual .来源可在 misc.cpp 中找到。 .

$ cd cryptopp
$ grep -R VerifyBufsEqual *
cryptlib.cpp:   return VerifyBufsEqual(digest, digestIn, digestLength);
default.cpp:    if (!VerifyBufsEqual(check, check+BLOCKSIZE, BLOCKSIZE))
fipstest.cpp:   if (!VerifyBufsEqual(expectedModuleMac, actualMac, macSize))
fipstest.cpp:   if (VerifyBufsEqual(expectedModuleMac, actualMac, macSize))
misc.cpp:bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
misc.h:CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
pssr.cpp:   valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid;
pubkey.cpp: return VerifyBufsEqual(representative, computedRepresentative, computedRepresentative.size());
secblock.h:     return m_size == t.m_size && VerifyBufsEqual(m_ptr, t.m_ptr, m_size*sizeof(T));

我不清楚的是:VerifyBufsEqual 是基于相等长度的缓冲区。我不确定是否可以忽略“不等长”的情况。


Information Stack Exchange 上还有一个可能相关的问题:Timing attacks on password hashes .但我不确定它是否/如何推广到任意缓冲区比较。

这个问题激起了我对一般问题的答案的兴趣(这个问题一直存在):Constant time compares when array sizes are not equal? .这应该告诉我们是否在 VerifyBufsEqual (Crypto++)、CRYPTO_memcmp (OpenSSL) 等中有合适的工具。

关于c++ - 使用 Crypto++ 比较恒定时间密码摘要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21890441/

相关文章:

c++ - Ncurses和ostream类方法?

c++ - 套接字通过并发FTP传输接收到错误的数据

c++ - 如何禁用 Windows 用户通过 AdjustTokenPrivileges 手动更改系统时间的能力?

c - 尝试将哈希函数转换为 C

java - 感知哈希 (pHash) 图像颜色与灰度与阈值哪个是最佳输入源

java - 每次生成不同的密码哈希

c++ - 无法用 BER 解码 RSA 公钥

c++ - 获取 Cstrings 的控制台输入

compiler-construction - 将crypto++库与我的应用程序链接的正确方法

c++ - 将 AES 密文作为参数传递