How can I replicate this C# hashing in PHP? (toByteArray(), ComputeHash())

5 php c# sha1 hmac

I am trying to replicate the following code in PHP, It is example code for an API I have to interface with (The API & Example code is in C#, My app is in PHP 5.3). I'm not a C# developer and so am having trouble doing this.

// 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));
Run Code Online (Sandbox Code Playgroud)

I've tried many variations using pack() and other functions I've found online, but without anything to compare it to, I don't know if i've done it right or not.

Can any C# devs run the above code and post the values generated so I can use that to check/test against?

I've tried checking the MSDN to see what these methods do, but am stuck (and not sure if its correct, as I have nothing to compare it to).

PHP Pseudo Code

// 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));
Run Code Online (Sandbox Code Playgroud)

This sounds pretty simple and straightforwaard, but I'm not sure what a few of these C# methods do..

What do these C# methods do/return?

  • ComputeHash(byteArray) - Computed to what?.. what is returned?
  • System.Text.Encoding.ASCII.GetBytes(stringToSign); - What does this return?
  • new HMACSHA1(new Guid(apiToken).toByteArray()); No Secret Key?, what is the key used?

Any resources or help would be much appreciated. I tried variations of other answers on SO, but no joy.

Can I run the 3 lines of code somewhere online (like JSFiddle but for C#?) so I can see the output of each line?


Update - Bounty Added

我仍然遇到麻烦,我已经设法C#在Visual Studio中测试代码,但是在生成相同的哈希时却遇到了麻烦PHP.

我想要...

..上面的C#代码(具体来说,创建SHA1哈希的3行)要转换成PHP(看看Pseudo Code我上面发布的).我应该能够C#使用PHP 匹配哈希.

如果您有任何其他问题,请询问.

All*_*ice 3

问题在于 GUID 的字符串形式颠倒了 GUID 前 3 段中 2 个字符的十六进制数字的顺序。有关详细信息,请参阅示例中的注释: 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));
Run Code Online (Sandbox Code Playgroud)

我已针对您上面提供的 C# 代码测试了此代码,输出是相同的。但是,原始代码中指定的 GUID 无效,因此我必须稍微更改它。