Skip to content
Advertisement

Converting a php cryptography and hash_hmac(‘sha512’ code to c#

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;
}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement