Поэтому я работаю над сценарием PHP, который запрашивает API, который использует заголовки аутентификации HMAC. Тем не менее, я бился головой, пытаясь правильно закодировать подпись HMAC. У меня есть существующий скрипт nodejs для работы в качестве шаблона.
В сценарии nodejs подпись HMAC вычисляется с использованием следующего:
var crypto = require('crypto');
var hmac = [];
hmac.secret = 'ODc0YTM3YzUxODFlMWQ1YTdhMGQwY2NiZmE1N2Y1ODdjYzM5NTgyMDJhZjVkYTE4MmQxYzQ5ODk0M2QzNWQxYw==';
hmac.timestamp = 1457326475000;
hmac.path = '/account/';
hmac.message = hmac.path +'\n' + hmac.timestamp;
var sig = crypto.createHmac('sha512', new Buffer(hmac.secret, 'base64'));
hmac.signature = sig.update(hmac.message).digest('base64');
console.log(hmac);
это правильно вычисляет подпись HMAC как:
bWjIFFtFmWnj0 + xHLW2uWVa6M6DpbIV81uyUWwRFCJUg + 0Xyt40QWZWQjGvfPUB / JbjGZHUoso0Qv5JHMYEv3A ==.
Тем временем в PHP я использую:
<?php
$hmac['secret'] = 'ODc0YTM3YzUxODFlMWQ1YTdhMGQwY2NiZmE1N2Y1ODdjYzM5NTgyMDJhZjVkYTE4MmQxYzQ5ODk0M2QzNWQxYw==';
$hmac['nonce'] = '1457326475000';
$hmac['path'] = '/account/';
$hmac['message'] = $hmac['path']."\n".$hmac['nonce'] ;
$hmac['signature'] = base64_encode(hash_hmac('sha512',$hmac['message'],
$hmac['secret'], true));
print_r($hmac);
Приведенный выше код вычислит подпись HMAC как:
vqP49m / bk9nA4S3nMqW2r + kc2 + yBfwhY / jWGUfz6dlKJUMkC2ktiPnuCcymdSWl4XezZT5VKCATYfus86Hz / Гг ==
Работая по принципу «миллион обезьян взломали миллион клавиатур«Возможно, когда-нибудь удастся закодировать действительную подпись HMAC, я даже протестировал цикл, который перебирает все перестановки приведенного выше PHP-кода (с / без base64-кодирования сообщения, секретный; с / без двоичного кодирования HMAC, и т.д.) … безрезультатно.
Любые предложения для этого здесь, один измученный обезьяна?
Проблема в том, что вы не расшифровываете $hmac['secret']
прежде чем передать его hash_hmac()
,
Пытаться:
$hmac['secret'] = base64_decode($hmac['secret']);
$hmac['signature'] = base64_encode(
hash_hmac('sha512', $hmac['message'], $hmac['secret'], true)
);
Других решений пока нет …