在PHP中复制C#SHA256哈希

在PHP中复制C#SHA256哈希,c#,php,hash,C#,Php,Hash,我正在尝试访问一个API,它需要PHP中的头授权。此授权部分使用带有密钥的SHA256哈希。API创建者为我提供了一个用C#编写的.exe来创建此哈希。但是,现在使用.exe是不可行的,我想用PHP来实现 下面是生成哈希的正确C#代码 var url = "[url]"; var userId = "apiuser"; var timestamp = "Fri, 14 Jul 2017 00:28:07 GMT"; // DateTime.UtcNow; var keyString = "

我正在尝试访问一个API,它需要PHP中的头授权。此授权部分使用带有密钥的SHA256哈希。API创建者为我提供了一个用C#编写的.exe来创建此哈希。但是,现在使用.exe是不可行的,我想用PHP来实现

下面是生成哈希的正确C#代码

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#散列:CfS6zNR3pTP0kJIA0RJ7LUwQXjONroVIg65bDvuefH8=

下面是我在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散列:6cI0NV6AKYILTyYHs+hyA0+Q4iRfMw+H2FGsp7uKOFM=

我尝试了很多不同的方法来处理PHP生成的哈希,但没有一种方法是相同的。此外,我不确定PHP日期是否与C#日期相同,但这可以等待。感谢您的帮助。

比较一下

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

$hashdata = 'GET\n' . $url . '\n' . $user . '\n' . $timestamp;
您缺少结尾“\n”,正如@Fred ii所指出的,PHP只将\n视为“not”中的字符转义:

或者仅此而已,因为PHP计算“”中的变量:

PHP中的单引号与双引号:

  • 单引号“hello$person\r\n”中的字符串与所写内容完全相同。与\r\n回车换行符对不同,它是4个字符'\''''''''\''''''''\n'和$person显示为'“$person”
  • 双引号中的字符串“hello$person\r\n”以两种方式处理:1。任何$name都被视为变量,并由该变量的值替换(如果该变量不存在,则为空字符串)。2.字符转义与\r\n和\r\n在其他语言中的工作方式类似

感谢您的回复,真不敢相信我错过了“\n”。我确实加了这个,但当我再次测试时,它仍然是不同的。hash_hmac()中的“true”参数应该与编码utf8相同?无论如何,我用utf8_encode($hashdata)进行了测试,但它没有改变结果。\n需要在双引号内,我确实相信phpGood catch@Fred ii,让我们看看OP现在会说什么。希望它是“Eureka!”谢谢你们的工作人员:)你们能给我解释一下为什么需要它吗?把你们所有的\n都放在双引号里,在php中试试
$hashdata = "GET\n" . $url . "\n" . $user . "\n" . $timestamp . "\n" ;
$hashdata = "GET\n$url\n$user\n$timestamp\n" ;