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.
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=
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"