C # equivalente a hash_hmac en PHP

usando .NET y C # necesito proporcionar una cadena de integridad usando HMAC SHA512 a un servidor PHP. Usando en 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()); 

Pero no coincide con el código PHP hash_hmac () PHP:

 $hmac = strtoupper(hash_hmac($pbx_hash, $msg, $binKey)); 

Intento cambiar la encoding en C # (utf8, ASCII, Unicode) sin éxito.

He intentado muchas soluciones encontradas en la red pero nada da la misma cadena 🙁

No puedo cambiar el código PHP, y no veo lo que está mal en C #

Editar Esto es ByteToString (copiado del comentario):

 static string ByteToString(byte[] buff) { string sbinary = ""; for (int i = 0; i < buff.Length; i++) { sbinary += buff[i].ToString("X2"); /* hex format */ } return (sbinary); } 

Después de muchos años, descubrí que obtengo los mismos resultados si PHP hash_hmac key es una cadena, no un byte Array. Parece que el problema está en la función PHP convert $ binKey = paquete (“H *”, $ keyTest);

El problema debe ser la representación real de los datos clave / mensaje.

Vea las siguientes pruebas:

PHP

 #!/usr/bin/php  

Salida (en vivo a través de 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; } } 

Salida (en vivo a través de http://ideone.com/JdpeL ):

 Result: 6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A 

Por lo tanto, verifique el conjunto de caracteres / encoding de los datos de entrada de PHP. También verifique el algoritmo real (en $pbx_hash ).

  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); } } 

Como dicho superior, el problema era con PHP Pack (función H * utilizada para convertir clave a matriz de bytes. C # Getbytes no da el mismo resultado (utf8, asci, unicode …). La solución se encuentra aquí: http: / /www.nuronconsulting.com/c-pack-h.aspx estaba bien para mí. ¡Ahora HMAC de C # coincide con 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 gracias a todos por su ayuda.