如何在PHP中复制这种C#哈希?(toByteArray(),ComputeHash())

如何在PHP中复制这种C#哈希?(toByteArray(),ComputeHash()),c#,php,sha1,hmac,C#,Php,Sha1,Hmac,我试图在PHP中复制以下代码,这是我必须使用的API的示例代码(API和示例代码在C#中,我的应用程序在PHP5.3中)。我不是C#developer,所以在这方面遇到了麻烦 // 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 t

我试图在
PHP
中复制以下代码,这是我必须使用的API的示例代码(API和示例代码在
C#
中,我的应用程序在
PHP5.3
中)。我不是C#developer,所以在这方面遇到了麻烦

// 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));
我已经尝试过使用我在网上找到的许多变体和其他功能,但是没有任何东西可以比较,我不知道我是否做对了

任何C#dev都可以运行上面的代码并发布生成的值,以便我可以使用它来检查/测试吗

我已经试着检查了,看看这些方法是怎么做的,但是我被卡住了(不确定它是否正确,因为我没有什么可以比较的)

PHP伪代码 这听起来很简单,但我不确定这些C#方法中的一些能做什么

这些
C#
方法做什么/返回什么?
  • ComputeHash(byteArray)
    -计算到什么?。。归还什么
  • System.Text.Encoding.ASCII.GetBytes(stringToSign)-返回什么
  • new-HMACSHA1(新的Guid(apiToken.toByteArray())没有密钥?使用的密钥是什么
任何资源或帮助都将不胜感激。 我试过各种各样的答案,但没有乐趣

我是否可以在线运行3行代码(如
JSFiddle
但对于
C#
?),以便查看每行的输出


更新-已添加赏金 在这方面仍然有问题,我已经设法在Visual Studio中测试了
C#
代码,但是在
PHP
中生成相同的哈希时遇到了问题

我想。。。 。。上面的
C#
代码(特别是创建
SHA1
hash的3行代码)将被转换为PHP(查看上面发布的
Pseudo code
I)。我应该能够使用PHP匹配
C#
hash


如果您还有其他问题,请提问。

当我不需要测试代码时,这很容易:p

-这相当于HMACSHA1 c级

字符串hash_hmac(字符串$algo,字符串$data,字符串$key[,bool$raw_output=false])

所以$algo=“sha1”

$data是您的$stringToSign——因为它已经是ascii字符串(我希望如此)——C#只是取了相同的字节等价物

新Guid(apiToken).toByteArray()->这是Guid的16字节(16*8=128)表示形式,即32*4=128位。这是关键

$key是一个字符串,因此您需要$apiToken的等效ASCII字符串(即32个十六进制字符-第一条带/忽略中间的破折号)-E10247631234567891E0T32E4E7EB316(更正该键-它不能有“T”)

这将返回一个二进制字符串-您需要将其转换为base64编码

$final = base64_encode ($almostResult)

这应该可以做到…享受:)

问题是GUID的字符串形式颠倒了GUID前3段中2个字符的十六进制数的顺序。有关更多信息,请参见示例中的注释:

以下代码应该可以工作:

$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));
$apiTokenId=1887;
$apiToken=“E1024763-1234-5678-91E0-FF2E4E7EB316”;
$stringToSign='';
$hexStr=str_replace('-','$apitonk);
$c=爆炸('-',块分割($hexStr,2'-');
$hexArr=数组($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='';
对于($i=0;$i<16;++$i){
$num=hexdec($hexArr[$i]);
$keyStr.=chr($num);
}
$stringToSign.=“POST”。“用户代理”。"http://api.com/post";
$hmacsha1=base64_编码(hash_hmac('sha1',$stringToSign,$keyStr,true));

我已经用上面提供的C代码测试了这段代码,结果是一样的。但是,原始代码中指定的GUID无效,因此我不得不稍微更改它。

我遇到了几乎相同的问题,在谷歌搜索之后,我发现了以下帖子:

在PHP中,字符串已经是字节数组了。您遇到的具体问题是什么


对我来说,解决方案只是
base64_encode('apikey')

您是否阅读了文档以了解您提出的任何问题?1) ComputeHash对字节数组进行散列,在本例中使用HMACSHA1。2) Encoding.ASCII.GetBytes返回以ASCII编码的字符串(作为字节)。3) 您正在向HMACSHA1.var apiToken=“E1024763-1234-5678-91E0-T32E4E7EB316”的构造函数提供密钥;那是打字错误吗?GUIDs不能有一个“t”-所有十六进制:)@JonSkeet我发现在问了这个问题后不久,我的问题是用PHP做等价的事情,我知道我需要hash_hmac func,但不知道我需要hexdec,现在想一想,这只是一个与PHP相关的问题,我只想掩盖我的私人问题,我用一些随机字符替换了它,你的眼睛很敏锐;)
$almostResult = hash_hmac ("sha1" , $stringToSign, $hexKey, true)
$final = base64_encode ($almostResult)
$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));