Я пытаюсь реплицировать следующий код в PHP
Это пример кода для API, с которым мне нужно взаимодействовать (код API и пример находится на C#
, Мое приложение находится в PHP 5.3
). Я не разработчик C #, и поэтому у меня проблемы с этим.
// C# Code I am trying to replicate in PHP var apiTokenId = 1887; var apiToken = "E1024763-1234-5678-91E0-T32E4E7EB316"; // Used to authenticate our request by the API (which is in C#) var stringToSign = string.Empty; stringToSign += "POST"+"UserAgent"+"http://api.com/post"; // Here is the issue, How can I do the following 3 lines in PHP? // No "secret key" provided?.. How do I do this in PHP? var hmacsha1 = new HMACSHA1(new Guid(apiToken).toByteArray()); // Make a byte array with ASCII encoding. byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(stringToSign); // Finally, 'computeHash' of the above (what does this do exactly?!) var calculatedSignature = Convert.ToBase64String(hmacsha1.ComputeHash(byteArray));
Я пробовал много вариантов с помощью pack()
и других функций, которые я нашел в Интернете, но без каких-либо сравнений, я не знаю, правильно ли я сделал это.
Могут ли любые разработчики C # выполнить приведенный выше код и опубликовать полученные значения, чтобы я мог использовать это для проверки / проверки?
Я попытался проверить MSDN, чтобы узнать, что делают эти методы, но я застрял (и не уверен, что это правильно, поскольку мне нечего сравнивать).
// Set vars $apiToken = 'E1024763-1234-5678-91E0-T32E4E7EB316'; $apiTokenId = '1887'; $stringToSign = "POST"."UserAgent"."http://api.com/post"; // HowTo: Build a `byteArray` of our apiToken? (i think) // C#: var hmacsha1 = new HMACSHA1(new Guid(apiToken).toByteArray()); // HowTo: Convert our $stringToSign to a ASCII encoded `byteArray`? // C#: byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(stringToSign); // HowTo: Generate a base64 string of our (`hmacsha1`.ComputeHash(byteArray)) // C#: var calculatedSignature = Convert.ToBase64String(hmacsha1.ComputeHash(byteArray));
Это звучит довольно просто и прямолинейно, но я не уверен, что делают некоторые из этих методов C #.
C#
? ComputeHash(byteArray)
– ComputeHash(byteArray)
на что? .. что возвращается? System.Text.Encoding.ASCII.GetBytes(stringToSign);
-Что это возвращает? new HMACSHA1(new Guid(apiToken).toByteArray());
Нет секретного ключа ?, какой ключ используется? Любые ресурсы или помощь будут высоко оценены. Я попробовал варианты других ответов на SO, но без радости.
Могу ли я запустить 3 строки кода где-нибудь в сети (например, JSFiddle
но для C#
?), Чтобы я мог видеть вывод каждой строки?
У меня все еще есть проблемы с этим, мне удалось проверить код C#
в Visual Studio, но мне трудно получить тот же хеш, сгенерированный в PHP
.
.. приведенный выше код C#
(в частности, 3 строки, которые создают хэш SHA1
), которые должны быть преобразованы в PHP (ознакомьтесь с Pseudo Code
опубликованным выше). Я должен уметь сопоставлять хэш C#
с помощью PHP.
Если у вас есть другие вопросы, пожалуйста, спросите.
Проблема в том, что строковая форма GUID меняет порядок двухзначных шестнадцатеричных чисел в первых трех сегментах GUID. Для получения дополнительной информации см. Комментарии в этом примере: http://msdn.microsoft.com/en-us/library/system.guid.tobytearray.aspx
Следующий код должен работать:
$apiTokenId = 1887; $apiToken = "E1024763-1234-5678-91E0-FF2E4E7EB316"; $stringToSign = ''; $hexStr = str_replace('-','',$apiToken); $c = explode('-',chunk_split($hexStr,2,'-')); $hexArr = array($c[3],$c[2],$c[1],$c[0],$c[5],$c[4],$c[7],$c[6],$c[8],$c[9],$c[10],$c[11],$c[12],$c[13],$c[14],$c[15]); $keyStr = ''; for ($i = 0; $i < 16; ++$i) { $num = hexdec($hexArr[$i]); $keyStr .= chr($num); } $stringToSign .= "POST" . "UserAgent" . "http://api.com/post"; $hmacsha1 = base64_encode(hash_hmac('sha1',$stringToSign,$keyStr,true));
Я протестировал этот код против кода C #, который вы указали выше, и результат был таким же. Однако GUID, указанный в исходном коде, недействителен, поэтому мне пришлось слегка его изменить.
Это довольно легко, когда мне не нужно проверять код: P
http://php.net/manual/en/function.hash-hmac.php – это эквивалент класса C # HMACSHA1.
string hash_hmac (строка $ algo, строка $ data, строка $ key [, bool $ raw_output = false])
Итак, $ algo = "sha1"
$ data – ваш $ stringToSign – поскольку это уже строка ascii (надеюсь), C # просто принимал эквивалент байта.
new Guid (apiToken) .toByteArray () -> это 16-байтное (16 * 8 = 128) представление GUID – 32 * 4 = 128 бит. Это ключ.
$ key – строка, так что вам нужен эквивалент строки ASCII для вашего $ apiToken (который содержит 32 шестнадцатеричных символа – первая полоса / игнорирует штрихи между ними) – E10247631234567891E0T32E4E7EB316 (исправить ключ – он не может иметь «T»)
function hex2str($hex) { for($i=0;$i<strlen($hex);$i+=2) $str .= chr(hexdec(substr($hex,$i,2))); return $str; } $hexKey = hex2str($apiToken); //strip the dashes first
http://www.linux-support.com/cms/php-convert-hex-strings-to-ascii-strings/
Итак, вызов метода теперь работает:
$almostResult = hash_hmac ("sha1" , $stringToSign, $hexKey, true)
Это возвращает двоичную строку, которую нужно преобразовать в кодировку base64.
$final = base64_encode ($almostResult)
Это должно сделать это … наслаждайтесь 🙂