Преобразование PHP-скрипта HMAC-SHA1 в скрипт C #

Я работаю над проектом для использования API, и мне нужно сгенерировать подпись для заголовка вызова веб-службы. Документация по API предоставляет пример кода PHP с «заведомо хорошим» результатом, поэтому вы можете преобразовать его в ваш язык программирования по вашему выбору, и я столкнулся со стеной, и мне нужна помощь.

Я никогда раньше не работал с HMAC, так что это очень ново для меня, и я был бы признателен за ЛЮБОЙ отзыв.

В основном API предоставил образец PHP-скрипта и его результаты, так что вы можете написать свою версию и протестировать ее.

Вот пример PHP и его результат. Я опубликую свою текущую попытку C # с тем же кодом ниже. Еще раз, СПАСИБО заранее за любую помощь, которую вы можете предоставить.

    Use the following code example to compare your signature generation with a
known signature. The PHP code example that follows provides a reference to
the generation of a signature for a GET call into the CDRN API. Use your
code with the parameter values listed to validate the same signature is
generated.

<?php
$cdrn_domain = "api.testing.cdrn.com";
$secret_key = "cdrnpassword";
$api_version = "1.1";
$method_type = "GET";
$case_id = "12345";
$string_date = "2014-06-20T12:06:31Z";
$string_to_sign = $method_type . "\n" . $cdrn_domain . "\n" . "/partners/cases/$case_id" . "\n" . "" . "\n" . $api_version . "\n" . $string_date . "\n";

$signature = utf8_encode(base64_encode(hash_hmac('sha1', $string_to_sign, $secret_key, false)));
echo "SIGNATURE[$signature]";
?>

Выход:
ПОДПИСИ [NWY3N2Q0NTdmZDQxZjA4YWI0Njg3YTEwODljODdiNTEwMTdmMzNlZg ==]

Вот код C #, с которым мне нужна помощь:

    using System.Security.Cryptography;

string cdrn_domain = "api.testing.cdrn.com";
string secret_key = "cdrnpassword";
string api_version = "1.1";
string method_type = "GET";
string case_id = "12345";
string string_date = "2014-06-20T12:06:31Z";
string string_to_sign = method_type + "\n" + cdrn_domain + "\n" + "/partners/cases/" + case_id + "\n" + "" + "\n" + api_version + "\n" + string_date + "\n";

var result = CreateSignature(string_to_sign, secret_key);

public string CreateSignature(string message, string key)
{
var encoding = new System.Text.UTF8Encoding();
byte[] keyByte = encoding.GetBytes(key);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha1 = new HMACSHA1(keyByte, false))
{
byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}

Подпись, сгенерированная из моего кода C #:
X3fUV / 1B8Iq0aHoQich7UQF / М + 8 =

0

Решение

Проблема здесь в том, что вы (или API) кодировали неправильно хэш-значение

Из документации PHP для hash_hmac:

string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )

параметры

raw_output

     Когда установлено ПРАВДА, выводит необработанные двоичные данные. ЛОЖНЫЙ выводит строчные буквы

Итак, строка:

$signature = utf8_encode(base64_encode(hash_hmac('sha1', $string_to_sign, $secret_key, false)));

вместо создания хэш-значения HMAC в кодировке base64, на самом деле … закодированная в base64 строка с шестнадцатеричным значением в нижнем регистре хэша HMAC сам … в UTF-8 … ¯ \ _ (ツ) _ / ¯

Вы должны заметить, что, заменив третий параметр hash_mac от false в true, это на самом деле будет производить то же значение, что и ваша функция C #.

$signature = utf8_encode(base64_encode(hash_hmac('sha1', $string_to_sign, $secret_key, true)));

демо: ideone.com/lyrgKV


Очевидно, чтобы исправить ситуацию с вашей стороны (C #), чтобы она соответствовала выводу API, нам нужно использовать шестнадцатеричный хэш в нижнем регистре, прежде чем кодировать его в base64:

public static string CreateSignature(string message, string key)
{
var encoding = new System.Text.UTF8Encoding();
byte[] keyByte = encoding.GetBytes(key);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha1 = new HMACSHA1(keyByte, false))
{
byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);

string hashstring = BitConverter.ToString(hmacsha1.ComputeHash(messageBytes)).Replace("-","").ToLower();

return Convert.ToBase64String(encoding.GetBytes(hashstring));
}
}

демо: dotnetfiddle.net/FT4OQ4

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]