2012-01-09 31 views
7

Tengo la siguiente función en C#, una función de hash que necesito convertir a PHP. He intentado un par de cosas en PHP, pero no consigo los mismos resultados (no estoy del todo bien con .NET)Convertir la función de hash de C# en PHP

private static string GetSignature(string args, string privatekey) 
{ 
    var encoding = new System.Text.ASCIIEncoding(); 
    byte[] key = encoding.GetBytes(privatekey); 
    var myhmacsha256 = new HMACSHA256(key); 
    byte[] hashValue = myhmacsha256.ComputeHash(encoding.GetBytes(args)); 
    string hmac64 = Convert.ToBase64String(hashValue); 
    myhmacsha256.Clear(); 
    return hmac64; 
} 

Uno (mal) intento en PHP es la siguiente:

function encode($data,$key) 
{ 
    return base64_encode(hash_hmac('sha256', $data, $key)); 
} 

La RESPUESTA

Una ligera variación de lo que se sugiere a continuación por DampeS8N trabajó para mí.

function encode($data,$key) 
{ 
    iconv_set_encoding("input_encoding", "ASCII"); 
    iconv_set_encoding("internal_encoding", "ASCII"); 
    iconv_set_encoding("output_encoding", "ASCII"); 

    return base64_encode(hash_hmac('sha256', $data, $key, true)); 
} 

Por favor, tampoco el cuarto parámetro de hash_hmac - ahora se establece como true para la salida en bruto como datos binarios

+0

Debe aceptar la respuesta de DampeS8N si lo encaminó en la dirección correcta. – jgauffin

Respuesta

6

Sospecho que la primera línea de su código .NET es el culpable. PHP has no encoding for the string en sí y entonces, cuando llega el momento de hash, o bien hash los bytes del formato de la cadena PHP interna (improbable, ¿alguien más puede confirmar?) O lo más probable es que se convierta primero en algo diferente. En este caso probablemente unicode que decididamente no es el mismo byte que la cadena estaría en ASCII como lo está solicitando .net.

Mi consejo sería asegurarse de que PHP también utiliza ASCII, with iconv, para permitir la interoperabilidad.

function encode($data,$key) 
{ 
    return base64_encode(hash_hmac('sha256', iconv(iconv_get_encoding("internal_encoding"), "ASCII", $data), iconv(iconv_get_encoding("internal_encoding"), "ASCII", $key))); 
} 

no se puede estar seguro de que el código anterior de salida de los hashes deseados, sin embargo, como no tengo .net útil para probar el código inicial. Pero esto podría apuntar en la dirección correcta.

Si esto no funciona, el valor dentro de iconv_get_encoding( podría ser el culpable, pruebe "output_encoding" o "input_encoding" también. También es posible que deba establecer estos mismos valores en ASCII con iconv_set_encoding(.

¡Buena suerte!


¡Actualización! Esto es lo que funcionó en última instancia:

function encode($data,$key) 
{ 
    iconv_set_encoding("input_encoding", "ASCII"); 
    iconv_set_encoding("internal_encoding", "ASCII"); 
    iconv_set_encoding("output_encoding", "ASCII"); 

    return base64_encode(hash_hmac('sha256', $data, $key, true)); 
} 
+0

Gracias por esto. Tiene sentido, aunque no parece funcionar. Tengo el mismo problema que no tengo entorno .net para probar. También creo que todavía necesito esta codificación. GetBytes (privatekey); – 32423hjh32423

+1

Eso debería estar obteniendo los bytes brutos del ASCII para la clave. Debido a la escritura dinámica en PHP, puede ser muy difícil llegar a eso y controlarlo. Estoy seguro de que es una combinación de establecer las cosas correctas con iconv_set_encoding (para asegurar que hash_hmac (no está deshaciendo todo el trabajo duro que has hecho con iconv). – DampeS8N

+0

Gracias. Respuesta publicada arriba. – 32423hjh32423