Конвертировать хеш-функцию C # в PHP - PullRequest
7 голосов
/ 09 января 2012

У меня есть следующая функция в C #, функция хеширования, которую мне нужно преобразовать в PHP. Я пробовал несколько вещей в PHP, но я не получаю те же результаты (я не совсем хорошо с .NET)

private static string GetSignature(string args, string privatekey)
{
    var encoding = new System.Text.ASCIIEncoding();
    byte[] key = encoding.GetBytes(privatekey);
    var myhmacsha256 = new HMACSHA256(key);
    byte[] hashValue = myhmacsha256.ComputeHash(encoding.GetBytes(args));
    string hmac64 = Convert.ToBase64String(hashValue);
    myhmacsha256.Clear();
    return hmac64;
} 

Одна (неправильная) попытка в PHP такова:

function encode($data,$key)
{
    return base64_encode( hash_hmac('sha256', $data, $key ) );
}

ОТВЕТ

Небольшое изменение того, что было предложено ниже DampeS8N, сработало для меня.

function encode($data,$key)
{
    iconv_set_encoding("input_encoding", "ASCII");
    iconv_set_encoding("internal_encoding", "ASCII");
    iconv_set_encoding("output_encoding", "ASCII");

    return base64_encode( hash_hmac('sha256', $data, $key, true ) );
}

Пожалуйста, не четвертый параметр hash_hmac - теперь установлен в true для необработанного вывода в виде двоичных данных

1 Ответ

6 голосов
/ 09 января 2012

Я подозреваю, что самой первой строкой вашего кода .net является виновник. PHP не имеет никакой кодировки для самой строки , поэтому, когда приходит время хэшировать, он либо хэширует байты внутреннего формата строки PHP (маловероятно, может кто-то еще подтвердить?), Либо, скорее всего, конвертирует что-то еще первый. В этом случае, вероятно, Unicode, который определенно не совпадает с байтами, что строка будет в ASCII, как запрашивает .net.

Мой совет - убедиться, что PHP также использует ASCII, с иконкой , для обеспечения взаимодействия.

function encode($data,$key)
{
    return base64_encode( hash_hmac('sha256', iconv( iconv_get_encoding( "internal_encoding"), "ASCII", $data ), iconv( iconv_get_encoding( "internal_encoding"), "ASCII", $key ) ) );
}

Я не могу быть уверен, что приведенный выше код выведет желаемые хэши, поскольку у меня нет .net, удобного для тестирования исходного кода. Но это может указать вам правильное направление.

Если это не сработает, виновником может быть значение внутри iconv_get_encoding(, попробуйте также "output_encoding" или "input_encoding". Также возможно, что вам нужно будет установить эти же значения в ASCII с помощью iconv_set_encoding(.

Удачи!


Обновление! Вот что в итоге сработало:

function encode($data,$key)
{
    iconv_set_encoding("input_encoding", "ASCII");
    iconv_set_encoding("internal_encoding", "ASCII");
    iconv_set_encoding("output_encoding", "ASCII");

    return base64_encode( hash_hmac('sha256', $data, $key, true ) );
}
...