在Qt中如何实现HMAC-SHA1算法

6

我正在尝试在我的C++/Qt应用程序中实现HMAC-SHA1算法。 我已经有了Sha1算法的方法,我只需要理解其中的HMAC部分。

以下伪代码来自维基百科:

 1 function hmac (key, message)
 2     if (length(key) > blocksize) then
 3         // keys longer than blocksize are shortened
 4         key = hash(key)
 5     end if
 6     if (length(key) < blocksize) then
 7         // keys shorter than blocksize are zero-padded
 8         key = key ∥ zeroes(blocksize - length(key))
 9     end if
10
11     // Where blocksize is that of the underlying hash function
12     o_key_pad = [0x5c * blocksize] ⊕ key
13     i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR)
14     // Where ∥ is concatenation
15     return hash(o_key_pad ∥ hash(i_key_pad ∥ message))
16 end function

什么是块大小?第8行的零函数是做什么的?如何用C ++表示第12-13行?

5个回答

6

1. 什么是块大小?

通常,哈希算法通过将数据切成固定大小的数据块(也称为“块”)来处理数据。对于SHA1算法,通常的块大小为64字节。

2. 第8行的zeros函数是做什么的?

它(正如注释所述)在密钥的末尾添加“零”,以使其长度与“块”大小相匹配。

3. 如何用C++表示第12-13行?

我认为您正在寻找异或运算符:^

例如:

o_key_pad = (0x5c * blocksize) ^ key; // Actually, it should be 0x5c5c5c... repeated enough so that it matches key size.

简要说明:这与Qt无关,您可能希望在“原生”C++中执行此操作,以便最终可以在非Qt项目中重用它。我认为Qt很棒,但显然您不需要它来实现这个。


块大小为64个八位字节(512位)。"0x5C * blocksize"应该是一个由blocksize个值为0x5C的字节组成的序列。 - sellibitze

5

这篇文章有一个可行的实现:

/**
 * Hashes the given string using the HMAC-SHA1 algorithm.
 *
 * \param key The string to be hashed
 * \param secret The string that contains secret word
 * \return The hashed string
 */
static QString hmac_sha1(const QString &key, const QString &secret) {
   // Length of the text to be hashed
   int text_length;
   // For secret word
   QByteArray K;
   // Length of secret word
   int K_length;

   K_length = secret.size();
   text_length = key.size();

   // Need to do for XOR operation. Transforms QString to
   // unsigned char

   K = secret.toAscii();

   // Inner padding
   QByteArray ipad;
   // Outer padding
   QByteArray opad;

   // If secret key > 64 bytes use this to obtain sha1 key
   if (K_length > 64) {
      QByteArray tempSecret;

      tempSecret.append(secret);

      K = QCryptographicHash::hash(tempSecret, QCryptographicHash::Sha1);
      K_length = 20;
   }

   // Fills ipad and opad with zeros
   ipad.fill(0, 64);
   opad.fill(0, 64);

   // Copies Secret to ipad and opad
   ipad.replace(0, K_length, K);
   opad.replace(0, K_length, K);

   // XOR operation for inner and outer pad
   for (int i = 0; i < 64; i++) {
      ipad[i] = ipad[i] ^ 0x36;
      opad[i] = opad[i] ^ 0x5c;
   }

   // Stores hashed content
   QByteArray context;

   // Appends XOR:ed ipad to context
   context.append(ipad, 64);
   // Appends key to context
   context.append(key);

   //Hashes inner pad
   QByteArray Sha1 = QCryptographicHash::hash(context, QCryptographicHash::Sha1);

   context.clear();
   //Appends opad to context
   context.append(opad, 64);
   //Appends hashed inner pad to context
   context.append(Sha1);

   Sha1.clear();

   // Hashes outerpad
   Sha1 = QCryptographicHash::hash(context, QCryptographicHash::Sha1);

   // String to return hashed stuff in Base64 format
   QByteArray str(Sha1.toBase64());

   return str;
}

2

这不执行HMAC。 - Layne Bernardo
1
@LayneBernardo 我用它来进行HMAC计算,Qt Wiki上称它支持HMAC-SHA1 - Daniel Nicoletti

1

看看QCA库。它已经提供了所有主要加密算法的实现。


我知道那个库,但由于我只需要一个函数,我不想将整个库合并到我的软件中。 - Gerstmann

1
你还应该看一下 QCryptographicHash,因为它可以帮助你解决问题中的sha1部分。

QCryptographicHash不提供HMAC-SHA1算法。 - Gerstmann
不,它并不具备此功能。但是你可以利用它来构建自己的hmac-sha1。 - sellibitze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接