Question

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.

Was it helpful?

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=

OTHER TIPS

He also asked it as byte array, it's the most important because have to use char to byte conversion:

//Conversion object
System.Text.UTF8Encoding  encoding = new System.Text.UTF8Encoding();

//Your any String text
String stringText = "g" + Convert.ToChar(0) + "poo";

//Convert to the wanted byte array
byte[] byteArray = encoding.GetBytes(stringText);

You can also do the same thing in a single line, if you prefer :)

byte[] byteArray = new System.Text.UTF8Encoding().GetBytes("g" + Convert.ToChar(0) + "poo");

You can use Convert.ToChar(Int32) method to represent unicode values as characters.

Usage: "g" + Convert.ToChar(0) + "poo"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top