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

£可爱£侵袭症+ 提交于 2019-12-05 12:56:54

The issue is that the string form of the GUID reverses the order of the 2-character hexadecimal numbers in the first 3 segments of the GUID. For more information see the comments in the example at: http://msdn.microsoft.com/en-us/library/system.guid.tobytearray.aspx

The following code should work:

$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));

I've tested this code against the C# code you provided above and the output was the same. However, the GUID specified in the original code is not valid so I had to change it slightly.

It's pretty easy, when i don't have to test the code :P

http://php.net/manual/en/function.hash-hmac.php - that's the equivalent of the HMACSHA1 c# class.

string hash_hmac (string $algo , string $data , string $key [, bool $raw_output = false ] )

So $algo = "sha1"

$data is your $stringToSign - since that is already an ascii string (i hope) - the C# was just taking the byte equivalent of the same.

new Guid(apiToken).toByteArray() -> that's a 16 byte (16*8 = 128) representation of the GUID - which is 32*4 = 128 bits. This is the key.

$key is a string so you need the ASCII string equivalent for your $apiToken (which is 32 hex chars - first strip / ignore the dashes in between) - E10247631234567891E0T32E4E7EB316 (correct the key - it cannot have a "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/

So the method call now works :

$almostResult = hash_hmac ("sha1" , $stringToSign, $hexKey, true)

This returns a binary string - which you need to convert to base64 encoding.

$final = base64_encode ($almostResult)

That should do it...enjoy :)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!