Как реализовать алгоритм HMAC-SHA1 в Qt
Я пытаюсь реализовать алгоритм HMAC-SHA1 в моем приложении C++/Qt. У меня есть метод для алгоритма 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
что такое blocksize? Что делает нулевая функция в строке 8? Как вы выражаете строки 12-13 в C++?
4 ответов
1. Что такое blocksize ?
обычно хэш-алгоритм обрабатывает данные, разрезая их на куски данных фиксированного размера (ака. "блоки.)" Для SHA1 I обычный размер блока составляет 64 байта.
2. Что делает функция нулей в строке 8 ?
он (как говорится в комментарии) добавляет "нули" в конец ключа, чтобы его длина соответствовала размеру "блока".
3. Как вы выражаете строки 12-13 в C++ ?
Я думаю, вы ищете XOR оператор: ^
.
пример:
o_key_pad = (0x5c * blocksize) ^ key; // Actually, it should be 0x5c5c5c... repeated enough so that it matches key size.
просто короткая заметка: это не имеет ничего общего с Qt
и вы, вероятно, захотите сделать это в "raw"C++
Так что вы можете в конечном итоге использовать его в не -. Qt
отличный ИМХО, но вы явно не требуете его для реализации этого.
этот пост имеет рабочую реализацию:
/**
* 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;
}
взгляните на QCA библиотека. Это уже обеспечивает реализацию всех основных криптографических алгоритмов.
вы также должны взглянуть на QCryptographicHash, так как это может помочь вам с частью sha1 вашей проблемы.