【问题标题】:Self written HMAC function, not working correctly自己写的HMAC函数,不能正常工作
【发布时间】:2017-10-06 14:16:45
【问题描述】:

我编写了以下函数来生成引用 https://www.rfc-editor.org/rfc/rfc2104 的 HMAC-SHA1,但是,我生成的值似乎与 https://www.rfc-editor.org/rfc/rfc2202 上给出的值以及我在 https://www.freeformatter.com/hmac-generator.html 上测试的值不同。

例如,该函数应该为文本“The quick brown fox jumps over the lazy dog”使用“key”键生成de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9,但它会生成d3c446dbd70f5db3693f63f96a5931d49eaa5bab

谁能指出我的错误?

功能:

const int block_size = 64;
const int hash_output_size = 20;
const int ipadVal = 0x36;
const int opadVal = 0x5C;
std::string HMAC::getHMAC(const std::string &text)
{
// check if key length is block_size
// else, append 0x00 till the length of new key is block_size
int key_length = key.length();
std::string newkey = key;
if (key_length < block_size)
{
    int appended_zeros = block_size - key_length;
    // create new string with appended_zeros number of zeros
    std::string zeros = std::string(appended_zeros, '0');
    newkey = key + zeros;
}
if (key_length > block_size)
{
    SHA1 sha1;
    newkey = sha1(key);
}

// calculate hash of newkey XOR ipad and newkey XOR opad
std::string keyXipad = newkey;
std::string keyXopad = newkey;
for (int i = 0; i < 64; i++)
{
    keyXipad[i] ^= ipadVal;
    keyXopad[i] ^= opadVal;
}

// get first hash, hash of keyXipad+text
std::string inner_hash = getSHA1(keyXipad + text);

// get outer hash, hash of keyXopad+inner_hash
std::string outer_hash = getSHA1(keyXopad + inner_hash);

// return outer_hash
return outer_hash;
}

编辑:在行中

std::string zeros = std::string(appended_zeros, '0');

'0' 应该是 0:int 而不是 char。感谢@Igor Tandetnik。

【问题讨论】:

  • 您这样做只是为了教育,还是想在某个地方实际使用您的 HMAC 功能?因为如果是后者,你真的应该找一个库来为你做这件事。无论哪种方式,您确定 SHA1 类可以正常工作吗?
  • 只是为了教育。我已经针对在线工具测试了具有各种值的 SHA1,它运行良好。我什至设置了断点并测试了这些值及其 SHA1 值,一切似乎都是正确的。这就是为什么我现在很困惑。
  • '0' != 0 ....
  • 好吧……那是缺陷。谢谢你 :D 输出仍然不匹配。

标签: c++ hmac


【解决方案1】:

好的..所以环顾四周将我带到HMAC produces wrong results。原来,我在使用 hex 作为 ascii 时犯了同样的错误。

我使用了一个函数将 inner_hash 从 hex 转换为 ascii,然后一切都变得完美了。

函数的最终版本:

std::string HMAC::getHMAC(const std::string &text)
{
// check if key length is block_size
// else, append 0x00 till the length of new key is block_size
int key_length = key.length();
std::string newkey = key;
if (key_length < block_size)
{
    int appended_zeros = block_size - key_length;
    // create new string with appended_zeros number of zeros
    std::cout << "\nAppending " << appended_zeros << " 0s to key";
    std::string zeros = std::string(appended_zeros, 0);
    newkey = key + zeros;
}
if (key_length > block_size)
{
    SHA1 sha1;
    newkey = sha1(key);
}

// calculate hash of newkey XOR ipad and newkey XOR opad
std::string keyXipad = newkey;
std::string keyXopad = newkey;
for (int i = 0; i < 64; i++)
{
    keyXipad[i] ^= ipadVal;
    keyXopad[i] ^= opadVal;
}

// get first hash, hash of keyXipad+text
std::string toInnerHash = keyXipad + text;
std::string inner_hash = getHash(toInnerHash);

// get outer hash, hash of keyXopad+inner_hash
std::string toOuterHash = keyXopad + hex_to_string(inner_hash);
std::string outer_hash = getHash(toOuterHash);

// return outer_hash
return outer_hash;
}

hex_to_string 函数取自https://stackoverflow.com/a/16125797/3818617

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-13
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-17
    • 2013-04-09
    • 1970-01-01
    相关资源
    最近更新 更多