String with Convert.ToChar(0) hash result different than chr(0) in PHP when hashed hash_hmac

arrays, c#, chr, hash, php

Solution

I'm answering it again, because you have changed the whole question, so there's a new solution for your new question.

First, HMACSHA512 won't give the same result as your php code. By the way, your PHP generated hash is:

41028bb90af31dc6e7fa100a8ceb1e220bfedf67ea723292db9a4e1c14f69c73adf30eeba61ab054cdc91c82f6be2f76dd602392be630b5e99b1f86da1460cbe

To make the same result in C#, I created the `BillieJeansSHA512` class to make the hash equals as PHP. Also instead using `encoding.GetBytes` to convert byte[] to String I have created the method `ByteToString` to convert properly.

Ow, the following code is not simple as PHP, but I challenge you or anyone to do this simpler with the same PHP's hash! I dare you, I DOUBLE DARE YOU! Let's go to the code:

//These are not default imports, so you need to use it
using System.Text;
using System.Security.Cryptography;

//Before your actual class, you need to make your custom 512
public class BillieJeansSHA512 : HMAC
{
    public BillieJeansSHA512(byte[] key)
    {
        HashName = "System.Security.Cryptography.SHA512CryptoServiceProvider";
        HashSizeValue = 512;
        BlockSizeValue = 128;
        Key = (byte[])key.Clone();
    }
}

//Now, there's your actual class
public class HelloWorld{


    //First, use this method to convert byte to String like a boss
    static string ByteToString(byte[] buff)
    {
        string sbinary = "";
        for (int i = 0; i < buff.Length; i++)
            sbinary += buff[i].ToString("x2"); /* hex format */
        return sbinary;
    }    

    //Now let's get it started!
    public static void Main(String []args){
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

        //Your data
        var apiSecret = "5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425";
        var data = "payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529";
        var endPoint = "/info/orderbook";

        String message = endPoint + Convert.ToChar(0) + data;

        //Hash will be stored here
        String hash = "";

        //put your key at your custom 512
        BillieJeansSHA512 hmacsha512 = new BillieJeansSHA512(encoding.GetBytes(apiSecret));
        //hash'em all
        byte[] result = hmacsha512.ComputeHash(encoding.GetBytes(message));

        //convert bytes to string
        hash = ByteToString(result);

        //See it :)
        Console.WriteLine(hash);

        //Or if you using it at a web-page, this is it.
        //Response.Write(hash)

        //Now the easy part, convert it to base64
        var bytesTo64 = System.Text.Encoding.UTF8.GetBytes(hash);
        String hash64 = System.Convert.ToBase64String(bytesTo64);
    }
}

...well, this is it. `String hash` have the same hash as PHP does:

41028bb90af31dc6e7fa100a8ceb1e220bfedf67ea723292db9a4e1c14f69c73adf30eeba61ab054cdc91c82f6be2f76dd602392be630b5e99b1f86da1460cbe

and `String hash64` has the same encoded base64 value that PHP does:

NDEwMjhiYjkwYWYzMWRjNmU3ZmExMDBhOGNlYjFlMjIwYmZlZGY2N2VhNzIzMjkyZGI5YTRlMWMxNGY2OWM3M2FkZjMwZWViYTYxYWIwNTRjZGM5MWM4MmY2YmUyZjc2ZGQ2MDIzOTJiZTYzMGI1ZTk5YjFmODZkYTE0NjBjYmU=

Problem

I have a string in PHP which is being converted to a byte array and hashed. The string being converted to the byte array looks like: "g". chr(0) . "poo"; I need to equivalent byte array in C# so i can get the same hash.. EDIT: Here is the FULL problem, resulting hash is not the same. PHP ``` $api_secret = '5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425'; $data = 'payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529'; $endpoint = '/info/orderbook'; $signature = hash_hmac('sha512', $endpoint . chr(0) . $data, $api_secret); $result = base64_encode($signature); ``` C# ``` var apiSecret = "5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425"; var data = "payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529"; var endPoint = "/info/orderbook"; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); String message = endpPoint + Convert.ToChar(0) + data; var hmacsha512 = new HMACSHA512(encoding.GetBytes(message)); var result = Convert.ToBase64String(hmacsha512.Hash); ``` I've tried different base64 encoding like: ``` public static string ByteToString(byte[] buff) { string sbinary = ""; for (int i = 0; i < buff.Length; i++) sbinary += buff[i].ToString("X2"); /* hex format */ return sbinary; } ``` but ultimately the issue appears to be the byteArray that is hashed because of the chr(0) php uses.

Original source