使用.NET和C#我需要使用HMAC SHA512向PHP服务器提供完整性字符串。 在C#中使用:
Encoding encoding = Encoding.UTF8;
byte[] keyByte = encoding.GetBytes(key);
HMACSHA512 hmacsha512 = new HMACSHA512(keyByte);
byte[] messageBytes = encoding.GetBytes(message);
byte[] hashmessage = hmacsha512.ComputeHash(messageBytes);
return(ByteToString(hashmessage).toUpper());
但它与PHP hash_hmac()不匹配 PHP代码:
$hmac = strtoupper(hash_hmac($pbx_hash, $msg, $binKey));
我尝试用C#(utf8,ASCII,Unicode)更改编码但没有成功。
我在网上尝试了很多解决方案,但没有给出相同的字符串:(
我无法更改PHP代码,也看不到C#中的错误。
修改这是ByteToString
(从评论中复制):
static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
{
sbinary += buff[i].ToString("X2"); /* hex format */
}
return (sbinary);
}
经过多次发布后,发现如果PHP hash_hmac键是一个字符串,而不是一个字节数组,我会得到相同的结果。似乎问题出在PHP转换函数$ binKey = pack(“H *”,$ keyTest);
答案 0 :(得分:32)
问题必须是密钥/消息数据的实际表示。
参见以下测试:
PHP
#!/usr/bin/php
<?php
print strtoupper(hash_hmac("sha256", "message", "key"));
?>
输出(通过http://writecodeonline.com/php/直播):
6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A
C#
using System;
using System.Text;
using System.Security.Cryptography;
public class Program
{
private const string key = "key";
private const string message = "message";
private static readonly Encoding encoding = Encoding.UTF8;
static void Main(string[] args)
{
var keyByte = encoding.GetBytes(key);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
hmacsha256.ComputeHash(encoding.GetBytes(message));
Console.WriteLine("Result: {0}", ByteToString(hmacsha256.Hash));
}
}
static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
sbinary += buff[i].ToString("X2"); /* hex format */
return sbinary;
}
}
输出(通过http://ideone.com/JdpeL直播):
Result: 6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A
因此,检查PHP输入数据的字符集/编码。另请检查实际算法(在$pbx_hash
中)。
答案 1 :(得分:10)
private static string HashHmac(string message, string secret)
{
Encoding encoding = Encoding.UTF8;
using (HMACSHA512 hmac = new HMACSHA512(encoding.GetBytes(secret)))
{
var msg = encoding.GetBytes(message);
var hash = hmac.ComputeHash(msg);
return BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
}
}
答案 2 :(得分:3)
如上所述,问题在于PHP Pack(用于将密钥转换为字节数组的H *函数)。 C#Getbytes没有给出相同的结果(utf8,asci,unicode ......)。 在这里找到的解决方案:http://www.nuronconsulting.com/c-pack-h.aspx对我来说没问题。 现在来自C#的HMAC与PHP匹配!
public static byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1) hex += '0';
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
Manu感谢所有人的帮助。