如何在PHP中复制此C#散列? (toByteArray(),ComputeHash())
我试图在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()
和我在网上发现的其他function的许多变化,但没有任何可比性,我不知道我是否做得对。
任何C#开发人员都可以运行上面的代码并发布生成的值,以便我可以使用它来检查/测试吗?
我已经尝试检查MSDN以查看这些方法的作用,但是卡住了(并且不确定它是否正确,因为我没有什么要比较它)。
PHP伪代码
// 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)
– 计算什么?..返回什么? -
System.Text.Encoding.ASCII.GetBytes(stringToSign);
– 这会带来什么回报? -
new HMACSHA1(new Guid(apiToken).toByteArray());
没有密钥?,使用的密钥是什么?
任何资源或帮助将不胜感激。 我在SO上尝试了其他答案的变体,但没有快乐。
我可以在网上某处运行3行代码(比如JSFiddle
但对于C#
?)所以我可以看到每行的输出?
更新 – 赏金添加
我仍然遇到麻烦,我已经设法在Visual Studio中测试C#
代码,但是在获取PHP
生成的相同哈希时遇到了麻烦。
我想要…
..上面的C#
代码(具体来说,创建SHA1
哈希的3行)要转换成PHP(查看我上面发布的Pseudo Code
)。 我应该能够使用PHP匹配C#
哈希。
如果您有任何其他问题,请询问。
问题是GUID的字符串forms颠倒了GUID的前3个段中的2个字符的hex数字的顺序。 有关更多信息,请参阅示例中的注释: 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 – 相当于HMACSHA1 c#类。
string hash_hmac(string $ algo,string $ data,string $ key [,bool $ raw_output = false])
所以$ algo =“sha1”
$ data是你的$ stringToSign – 因为那已经是一个ascii字符串(我希望) – C#只是取相同的字节。
new Guid(apiToken).toByteArray() – >这是GUID的16字节(16 * 8 = 128)表示 – 这是32 * 4 = 128位。 这是关键。
$ key是一个字符串,所以你需要你的$ apiToken等效的ASCII字符串(这是32个hex字符 – 第一个条带/忽略它们之间的破折号) – E10247631234567891E0T32E4E7EB316(更正密钥 – 它不能有“T”)
function hex2str($hex) { for($i=0;$i
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)
应该这样做...享受:)