2016-01-22 3 views
4

Я должен построить авторизацию хэш из этой строки:HMAC-SHA-256 в PHP

kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F 

Этот секрет используется для HMAC хэш-функции:

LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ= 

авторизацию хеширования У меня есть чтобы произвести это:

P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI= 

есть некоторые вещи, чтобы заботиться о:

  1. Подпись должна быть построена с использованием HMAC-SHA-256, как указано в RFC 2104.
  2. Подпись должна быть закодирована с помощью Base64 URL-совместимого, как указано в RFC 4648 Section 5 (Безопасный алфавит).

Существует также несколько псевдо-код, указанный для генерации:

Signatur(Request) = new String(encodeBase64URLCompatible(HMAC-SHA-256(getBytes(Z, "UTF-8"), decodeBase64URLCompatible(getBytes(S, "UTF-8")))), "UTF-8") 

Я пробовал различные вещи в PHP, но не нашли правильный алгоритм еще. Это код, у меня сейчас:

if(!function_exists('base64url_encode')){ 
    function base64url_encode($data) { 
     $data = str_replace(array('+', '/'), array('-', '_'), base64_encode($data)); 
     return $data; 
    } 
} 

$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F"; 
$sec = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ="; 
$signature = mhash(MHASH_SHA256, $str, $sec); 
$signature = base64url_encode($signature); 

if($signature != "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=") 
    echo "wrong: $signature"; 
else 
    echo "correct"; 

Это дает эту подпись:

K9lw3V-k5gOedmVwmO5vC7cOn82JSEXsNguozCAOU2c= 

Как вы можете видеть, длина 44 символов правильно. Пожалуйста, помогите мне найти ошибку, эта простая проблема требует от меня часов, и нет решения.

+0

После прочтения вашего вопроса дважды я до сих пор не знаю, что ваш вопрос/вопрос есть. –

+0

@CharlotteDunois: Мне нужен хэш HMAC из строки для подписи и секрет. Если я пытаюсь сгенерировать его с помощью PHP, он терпит неудачу/дает неправильный хеш.Я считаю, что спецификации RFC не выполняются. – Richard

+0

Я думаю, что это в значительной степени из-за 'base64url_encode'. Если вам нужно, чтобы он был urlencoded по какой-либо причине, используйте «urlencode», а затем «urldecode» на сервере перед проверкой. –

ответ

4

Там есть несколько вещей, чтобы заметить:

  1. Ваш ключ в кодировке base64. Вы должны декодировать его, прежде чем сможете использовать его с функциями php. Это самая важная вещь, которую вы пропустили.
  2. Mhash устарели Hash расширение.
  3. Вы хотите, чтобы выходные данные были закодированы нестандартно, поэтому следует, что вам нужен необработанный вывод из функции hmac (по умолчанию php будет шестнадцатеричным кодированием).

Таким образом, используя расширение хеш это становится:

$key = "LRH9CAkNs-zoU3hxHbrtY0CUUcmqzibPeN7x6-vwNWQ="; 
$str = "kki98hkl-u5d0-w96i-62dp-xpmr6xlvfnjz:20151110171858:b2c13532-3416-47d9-8592-a541c208f755:hKSeRD98BHngrNa51Q2IgAXtoZ8oYebgY4vQHEYjlmzN9KSbAVTRvQkUPsjOGu4F"; 

function encode($data) { 
    return str_replace(['+', '/'], ['-', '_'], base64_encode($data)); 
} 

function decode($data) { 
    return base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); 
} 

$binaryKey = decode($key); 

var_dump(encode(hash_hmac("sha256", $str, $binaryKey, true))); 

Выходы:

string(44) "P-WgZ8CqV51aI-3TncZj5CpSZh98PjZTYxrvxkmQYmI=" 
+0

Большое спасибо, это именно то, что мне нужно! Проблема заключалась только в том, что «истина» в 'hash_hmac' и base64 расшифровывается ключом, который также нуждается в URL base64. – Richard

+0

hash_hmac всегда будет генерировать уникальную строку ...? – usama

+0

Нет, это вывод на основе входной строки и ключа. Дайте ему тот же ключ и строку, и он будет генерировать один и тот же вывод. – weirdan