Ошибка реализации HMAC

Я надеюсь, что это правильный форум; Я не был уверен, должен ли я спросить об этом в stackoverflow, криптографии или безопасности.

Итак, моя проблема в том, что функция php hash_hmac доступна только с php >= 5.1.2. Поскольку некоторые серверы не обновлены до этой версии, я написал свою собственную реализацию HMAC на основе хеш-функции php. Но код не дает такой же результат, как hash_hmac...

Так где же моя ошибка?

define("HASH_ALGO", "sha512");
define("HMAC_BLOCKSIZE", 64);

function computeHMAC($message, $key) {
    $ikey;
    $okey;
    $zero = hex2bin("00");
    $ipad = hex2bin("36");
    $opad = hex2bin("5C");

    /*
     *  HMAC construction scheme:
     *  $ikey = $key padded with zeroes to blocksize and then each byte xored with 0x36
     *  $okey = $key padded with zeroes to blocksize and then each byte xored with 0x5C
     *  hash($okey . hash($ikey . $message))
     */

    //Hash key if it is larger than HMAC_BLOCKSIZE
    if (strlen($key) > HMAC_BLOCKSIZE) {
        $key = hash(HASH_ALGO, $key, true);
    }
    //Fill ikey with zeroes
    for ($i = 0; $i < HMAC_BLOCKSIZE; $i++) {
        $ikey[$i] = $zero;
    }
    //Fill ikey with the real key
    for ($i = 0; $i < strlen($key); $i++) {
        $ikey[$i] = $key[$i];
    }
    //Until they get xored both keys are equal
    $okey = $ikey;
    //Xor both keys
    for ($i = 0; $i < HMAC_BLOCKSIZE; $i++) {
        $ikey[$i] ^= $ipad;
        $okey[$i] ^= $opad;
   }
   //Build inner hash
   $innerHash = hash(HASH_ALGO, $ikey . $message, true);
   //Build outer hash
   $outerHash = hash(HASH_ALGO, $okey . $innerHash, true);
   return $outerHash;
}

Функция была протестирована со следующим кодом:

echo hexDump(computeHMAC("Testolope", "Testkeyolope"));
echo hexDump(hash_hmac(HASH_ALGO, "Testolope", "Testkeyolope", true));

The output is the following:
HexDump (64 Bytes):
65 a8 81 af 49 f2 49 c5 64 7a 7a b7 a6 ac a0 4e 9e 9b 1a 3c 76 fc 48 19 13 33 e0 f8 82 be 48 52 1a 50 49 09 1e fe bf 94 63 5f 9d 36 82 3f 2f a1 43 b4 60 9f 9f e5 d1 64 c6 5b 32 22 45 07 c9 cb 

HexDump (64 Bytes):
d2 e9 52 d2 ab f0 db a7 60 e0 52 b0 5c 23 5a 73 d9 8c 78 8e 9e fb 26 82 54 7e f9 c8 f1 65 df 7f 97 44 fe 2b 1e 2b 6d d5 cb a4 ba c6 73 35 06 9c 0f c8 2d 36 8c b3 9b c4 48 01 5c c2 9f ce b4 08 

person K. Biermann    schedule 12.10.2014    source источник
comment
Я думаю, что это должно быть на StackOverflow. Это связано с криптографией и безопасностью, но вы просите решение для программирования. Я проголосовал за его перемещение, пожалуйста, не публикуйте тот же вопрос на StackOverflow.   -  person Luc    schedule 12.10.2014
comment
OK. Если я правильно понял систему миграции, у меня недостаточно репутации, чтобы самостоятельно перенести вопрос, поэтому мне нужно подождать, пока администратор сделает это за меня?   -  person K. Biermann    schedule 12.10.2014
comment
Хорошо, спасибо большое :D   -  person K. Biermann    schedule 12.10.2014


Ответы (1)


Проблема в том, что вы перепутали размер дайджеста и размер блока; SHA-512 имеет размер дайджеста 64, но размер блока 128.

Во-вторых, и $ikey, и $okey являются массивами, а не строками, поэтому вам нужно сначала преобразовать их обоих в строку:

$innerHash = hash(HASH_ALGO, join($ikey) . $message, true);
$outerHash = hash(HASH_ALGO, join($okey) . $innerHash, true);

Тем не менее, и hash(), и hash_hmac() задокументированы как доступные с версии 5.1.2, поэтому я не уверен, что это даст :)

person Ja͢ck    schedule 13.10.2014
comment
Спрашивающий упомянул, что hash() и hash_hmac() доступны с php ›= 5.1.2. Вероятно, самая большая причина, по которой спрашивающий спросил, заключается в том, что php, который он может использовать, будет ниже этого. - person Keith Park; 13.10.2014
comment
@KeithPark Не совсем, OP только упомянул, что функция hash_hmac php доступна только с php ›= 5.1.2 ... но его собственный код содержит использование hash(), который, согласно документации, также доступен только с 5.1.2. - person Ja͢ck; 13.10.2014
comment
О~ Извините, я неправильно понял, что вы имели в виду. Ты прав. Сам hash() нельзя использовать, если версия php ниже этой. - person Keith Park; 13.10.2014
comment
Ну, я не знал, что хэш официально поддерживается только в php › 5.1.2. Мой сервер php 5.0.2 и поддерживает хеш, но не hash_hmac o.O Может быть, он исправлен или какой-то модуль предлагает хеш-функцию, которая работает аналогично собственному хешу php... - person K. Biermann; 13.10.2014
comment
Почему вы используете такую ​​старую версию php? - person Bowersbros; 13.10.2014
comment
@ K.Biermann Это действительно необычно; возможно, он использует очень старую версию pecl/hash? - person Ja͢ck; 13.10.2014