2012-01-09 2 views
7

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

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 - теперь установлен верно для добытого в виде двоичных данных

+0

Вы должны принять ответ DampeS8Ns, если он указал вам в правильном направлении. – jgauffin

ответ

6

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

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

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)); 
} 
+0

Спасибо за это. Это совершенно разумно, хотя, похоже, не работает. У меня та же проблема, с которой у меня нет среды .net для тестирования. Я также думаю, что мне все еще нужна эта кодировка. GetBytes (privatekey); – 32423hjh32423

+1

Это должно быть просто получение необработанных байтов ASCII для ключа. Из-за динамического ввода в PHP это может быть очень трудно получить и контролировать. Я уверен, что это некоторая комбинация настройки правильных вещей с помощью iconv_set_encoding (чтобы гарантировать, что hash_hmac (не отменяет всю тяжелую работу, которую вы сделали с помощью iconv (сам). – DampeS8N

+0

Спасибо. Ответ отправлен выше. – 32423hjh32423

Смежные вопросы