0

I am trying to access an API which requires header authorization in PHP. This authorization uses in part a SHA256 hash with a key. The API creators have supplied me with an .exe written in C# to create this hash. However, now it is not feasible to use the .exe and I would like to do it in PHP.

Here is the correct C# code that makes the hash.

var url = "[url]";

var userId = "apiuser";

var timestamp = "Fri, 14 Jul 2017 00:28:07 GMT"; // DateTime.UtcNow;

var keyString = "dGVzdA==";

var hashData = String.Format("GET\n{0}\n{1}\n{2}\n", url, userId, timestamp); //.ToString("r"));

var key = Convert.FromBase64String(keyString);
string hashString;

using (var hmac = new HMACSHA256(key))
{
    var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(hashData));
    hashString = Convert.ToBase64String(hash);
}
Console.WriteLine(hashString);

C# Hash: CfS6zNR3pTP0kJIA0RJ7LUwQXjONroVIg65bDvuefH8=

Here is my attempt to replicate it in PHP

$key = "dGVzdA==";
$user = "apiuser";
$url = "[url]";

$timestamp = "Fri, 14 Jul 2017 00:28:07 GMT"; // date("D, d M Y H:i:s e");

$hashdata = 'GET\n' . $url . '\n' . $user . '\n' . $timestamp;

$generatedhash = base64_encode(hash_hmac('sha256', $hashdata, base64_decode($key), true));

print_r($generatedhash);

PHP Hash: 6cI0NV6AKYILTyYHs+hyA0+Q4iRfMw+H2FGsp7uKOFM=

I have attempted lots of different approaches to the PHP generated hash and none have been the same. Also I am not sure if the PHP date is the same as the C# date but that can wait. Any help is appreciated.

1
  • 1
    Put all your \n's inside double quotes, try that for the php Commented Jul 14, 2017 at 2:13

1 Answer 1

1

Compare this

var hashData = String.Format("GET\n{0}\n{1}\n{2}\n", url, userId, timestamp);

To this

$hashdata = 'GET\n' . $url . '\n' . $user . '\n' . $timestamp;

You're missing the ending '\n' and as @ Fred-ii- points out PHP will only treat \n as a character escape inside "" not '':

$hashdata = "GET\n" . $url . "\n" . $user . "\n" . $timestamp . "\n" ;

Or just this since PHP evaluates variables inside "":

$hashdata = "GET\n$url\n$user\n$timestamp\n" ;

Single vs. double quotes in PHP:

  • A string in single quotes 'hello $person\r\n' is taken exactly as written. Instead of the \r\n being a carriage return - line feed pair it is the 4 characters '\' 'r' '\' '\n' and $person appears as "$person".
  • A string in double quotes "hello $person\r\n" is processed in 2 ways: 1. any $name is treated as a variable and is replaced by that variable's value (empty string if the variable does not exist). 2. Character escapes like \r \n and \ work like in other languages.
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the response, can't believe I missed that "\n". I did add that on but it is still different when I tested again. The "true" parameter in hash_hmac() should be the same as encoding utf8? Anyway I did test with utf8_encode($hashdata) but it didn't change the result.
\n need to be inside of double quotes I do believe in the php
Good catch @Fred-ii-
Let's see what the OP will say now. Hopefully it will be "Eureka!"
Thank you guys that did work :) Can you explain to me why that was needed?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.