C# HMACSHA1 与 PHP hash_hmac
C# HMACSHA1 vs PHP hash_hmac
我正在尝试连接到 API 以使用 PHP 获取访问令牌,唯一的散列示例代码是用 C# 编写的。这是 C# 版本:
private static string GetHMACSignature(string privatekey, string message)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(privatekey);
Console.WriteLine("Key: "+ToReadableByteArray(keyByte));
System.Security.Cryptography.HMACSHA1 hmacsha1 = new System.Security.Cryptography.HMACSHA1(keyByte);
byte[] messageBytes = encoding.GetBytes(message);
Console.WriteLine("Message: "+ToReadableByteArray(messageBytes));
byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
Console.WriteLine("Hash: "+ToReadableByteArray(hashmessage));
return Convert.ToBase64String(hashmessage);
}
使用 "a1" 的 privatekey 和 "b1" 的 message,您将得到以下内容:
Key: 97, 49
Message: 98, 49
Hash: 219, 205, 149, 90, 235, 40, 133, 252, 91, 27, 240, 61, 201, 173, 220, 76, 73, 248, 92, 212
282VWusohfxbG/A9ya3cTEn4XNQ=
当我尝试 运行 PHP 中的等价物时,我得到相同的字节,但哈希不同:
$key = 'a1';
$message = 'b1';
$hmac = hash_hmac('sha1', $key, $message, true);
$hmac_base64 = base64_encode($hmac);
echo 'KEY BYTES: '.implode(',',$this->getByteArray($key)).'<br>';
echo 'MESSAGE BYTES: '.implode(',',$this->getByteArray($message)).'<br>';
echo 'HMAC BYTES: '.implode(',',$this->getByteArray($hmac)).'<br>';
echo 'HMAC: '.$hmac_base64;
function getByteArray($text) {
$secretBytes = array();
for($i = 0; $i < strlen($text); $i++)
{
$secretBytes[] = ord($text[$i]);
}
return $secretBytes;
}
结果:
KEY BYTES: 97,49
MESSAGE BYTES: 98,49
HMAC BYTES: 3,162,147,8,198,26,126,189,195,122,228,215,10,18,187,216,22,151,202,237
HMAC: A6KTCMYafr3DeuTXChK72BaXyu0=
我做错了什么?我在这里发现的很多问题都说要在 PHP 中将 hash_hmac 的二进制输出设置为 true,我已经做到了。最初我的消息中有 return (\r) 和换行符 (\n),所以我认为这可能是 ASCII 转换问题,但 运行 将其与 a1 和 b1 作为键和消息仍然不会导致匹配的散列,即使字节数组匹配。感谢您的帮助,提前致谢!
我对 PHP
了解不多,但根据 documentation on hash_hmac
看来您可能将 $key
和 $data
参数颠倒了。
来自文档:
hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = FALSE ] ) : string
所以,您似乎将 $message
作为键传递,将 $key
作为消息传递。
就是这样,我把密钥和消息颠倒了。谢谢!
我正在尝试连接到 API 以使用 PHP 获取访问令牌,唯一的散列示例代码是用 C# 编写的。这是 C# 版本:
private static string GetHMACSignature(string privatekey, string message)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(privatekey);
Console.WriteLine("Key: "+ToReadableByteArray(keyByte));
System.Security.Cryptography.HMACSHA1 hmacsha1 = new System.Security.Cryptography.HMACSHA1(keyByte);
byte[] messageBytes = encoding.GetBytes(message);
Console.WriteLine("Message: "+ToReadableByteArray(messageBytes));
byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
Console.WriteLine("Hash: "+ToReadableByteArray(hashmessage));
return Convert.ToBase64String(hashmessage);
}
使用 "a1" 的 privatekey 和 "b1" 的 message,您将得到以下内容:
Key: 97, 49
Message: 98, 49
Hash: 219, 205, 149, 90, 235, 40, 133, 252, 91, 27, 240, 61, 201, 173, 220, 76, 73, 248, 92, 212
282VWusohfxbG/A9ya3cTEn4XNQ=
当我尝试 运行 PHP 中的等价物时,我得到相同的字节,但哈希不同:
$key = 'a1';
$message = 'b1';
$hmac = hash_hmac('sha1', $key, $message, true);
$hmac_base64 = base64_encode($hmac);
echo 'KEY BYTES: '.implode(',',$this->getByteArray($key)).'<br>';
echo 'MESSAGE BYTES: '.implode(',',$this->getByteArray($message)).'<br>';
echo 'HMAC BYTES: '.implode(',',$this->getByteArray($hmac)).'<br>';
echo 'HMAC: '.$hmac_base64;
function getByteArray($text) {
$secretBytes = array();
for($i = 0; $i < strlen($text); $i++)
{
$secretBytes[] = ord($text[$i]);
}
return $secretBytes;
}
结果:
KEY BYTES: 97,49
MESSAGE BYTES: 98,49
HMAC BYTES: 3,162,147,8,198,26,126,189,195,122,228,215,10,18,187,216,22,151,202,237
HMAC: A6KTCMYafr3DeuTXChK72BaXyu0=
我做错了什么?我在这里发现的很多问题都说要在 PHP 中将 hash_hmac 的二进制输出设置为 true,我已经做到了。最初我的消息中有 return (\r) 和换行符 (\n),所以我认为这可能是 ASCII 转换问题,但 运行 将其与 a1 和 b1 作为键和消息仍然不会导致匹配的散列,即使字节数组匹配。感谢您的帮助,提前致谢!
我对 PHP
了解不多,但根据 documentation on hash_hmac
看来您可能将 $key
和 $data
参数颠倒了。
来自文档:
hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = FALSE ] ) : string
所以,您似乎将 $message
作为键传递,将 $key
作为消息传递。
就是这样,我把密钥和消息颠倒了。谢谢!