I am having troubles converting a cryptography code from php to c#, and i would really appreciate some help, here is the php code
$postdata = http_build_query($param, '', '&'); $hash = '/' .$method . hash('sha256', $nonce . $postdata, true); $signature = hash_hmac('sha512', $hash, base64_decode($this->secret), true); $signature = base64_encode($signature);
example data are the following:
$method = 'auth/register'; $param = [ "email" => 'test@test.com', "password" => 'Password1234', "customerId" => '1234', ];
what i did so far is
string nonce ="123456789" string param="email=test@test.com.lb&password=Devilmaycry@5&customerId=20210309035037" public string CalculateSignature(string nonce,string pth) { string hash =pth+ ComputeSha256Hash(nonce); Encoding ascii = Encoding.ASCII; HMACSHA512 hmac = new HMACSHA512(ascii.GetBytes(client_secret)); string calc_sig = Convert.ToBase64String(hmac.ComputeHash(ascii.GetBytes(hash))); return calc_sig; } static string ComputeSha256Hash(string rawData) { // Create a SHA256 using (SHA256 sha256Hash = SHA256.Create()) { // ComputeHash - returns byte array byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData)); // Convert byte array to a string StringBuilder builder = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { builder.Append(bytes[i].ToString("x2")); } return builder.ToString(); } }
i am stuck in these two lines and i have no idea if i translate it them right
$signature = hash_hmac('sha512', $hash, base64_decode($this->secret), true); $signature = base64_encode($signature);
Advertisement
Answer
To compare both implementations, sample data is useful.
The following PHP code:
$nonce = 'nonce'; // sample data $secret = 'c2VjcmV0'; // sample data $method = 'auth/register'; $param = [ "email" => 'test@test.com', "password" => 'Password1234', "customerId" => '1234', ]; $postdata = http_build_query($param, '', '&'); print('Postdata: ' . $postdata . PHP_EOL); $hash = '/' . $method . hash('sha256', $nonce . $postdata, true); $signature = hash_hmac('sha512', $hash, base64_decode($secret), true); $signature = base64_encode($signature); print('Signature: ' . $signature . PHP_EOL);
returns as result:
Postdata: email=test%40test.com&password=Password1234&customerId=1234 Signature: EYvVUz9oyis+0EA+PkfSIbDlD2uhd75BTQmuOM8ousmXSUALnB4l/9CkdxjgVy0X2oMsSKiDlzPQq/RLDeU70w==
The C# implementation below gives the same result:
string method = "auth/register"; string nonce = "nonce"; string postdata = "email=test%40test.com&password=Password1234&customerId=1234"; string secret = "c2VjcmV0"; string signatureB64 = CalculateSignature(method, nonce, postdata, secret); Console.WriteLine(signatureB64);
with
public static string CalculateSignature(string method, string nonce, string postdata, string secret) { // Encoding byte[] methodBytes = Encoding.ASCII.GetBytes("/" + method); byte[] noncePostdataBytes = Encoding.ASCII.GetBytes(nonce + postdata); byte[] secretBytes = Convert.FromBase64String(secret); // $hash = '/' . $method . hash('sha256', $nonce . $postdata, true); byte[] nonceHash = SHA256.Create().ComputeHash(noncePostdataBytes); byte[] hash = concat(methodBytes, nonceHash); // $signature = hash_hmac('sha512', $hash, base64_decode($secret), true); byte[] signature = new HMACSHA512(secretBytes).ComputeHash(hash); // $signature = base64_encode($signature); string signatureB64 = Convert.ToBase64String(signature); return signatureB64; // EYvVUz9oyis+0EA+PkfSIbDlD2uhd75BTQmuOM8ousmXSUALnB4l/9CkdxjgVy0X2oMsSKiDlzPQq/RLDeU70w== }
and
public static byte[] concat(byte[] arr1, byte[] arr2) { byte[] newArr = new byte[arr1.Length + arr2.Length]; Buffer.BlockCopy(arr1, 0, newArr, 0, arr1.Length); Buffer.BlockCopy(arr2, 0, newArr, arr1.Length, arr2.Length); return newArr; }