Home > Back-end >  NodeJS - HMAC-SHA512 Equivalent code in Node from C#
NodeJS - HMAC-SHA512 Equivalent code in Node from C#

Time:07-20

using System;   
using System.Text;   
using System.Globalization;   
using System.Security.Cryptography;   
  
public class Program   
{   
    public static void Main()   
    {   
        var id = "integration";   
        var key = "SECRET_KEY";   
        var expiry = DateTime.UtcNow.AddDays(10);
        using (var encoder = new HMACSHA512(Encoding.UTF8.GetBytes(key)))   
        {   
            var dataToSign = id   "\n"   expiry.ToString("O", CultureInfo.InvariantCulture);   
            var hash = encoder.ComputeHash(Encoding.UTF8.GetBytes(dataToSign));   
            var signature = Convert.ToBase64String(hash);   
            var encodedToken = string.Format("SharedAccessSignature uid={0}&ex={1:o}&sn={2}", id, expiry, signature);   
            Console.WriteLine(encodedToken);   
        }   
    }   
}  

Reading the above C# Code and reading through crypto I believe that should translate to this....

const { createHmac } = require('crypto');

const id = 'integration';
const key = 'SECRET_KEY';
const expiry = new Date(new Date().setDate(new Date().getDate()   10));
const encodedkey = new TextEncoder().encode(key);
const encodedvalue = new TextEncoder().encode(id   '\n'   expiry.toJSON());
const signature = createHmac('sha512', encodedkey)
    .update(encodedvalue)
    .digest('base64');
console.log(`SharedAccessSignature uid=${id}&ex=${expiry.toJSON()}&sn=${signature}`);

But after running both and testing the produced output against azure the C# output works while the Node output doesn't. (relevant: https://docs.microsoft.com/en-us/rest/api/apimanagement/apimanagementrest/azure-api-management-rest-api-authentication)

What am I missing?

CodePudding user response:

Was found by a colleague

The issue is expiry.ToString("O", CultureInfo.InvariantCulture) produces the Date string... "2022-07-28T05:19:33.2720140Z" new Date().toJSON() produces the Date string... "2022-07-28T05:18:33.778Z"

The difference is the decimal places, to fix this I changed the above code to this and works great....

const { createHmac } = require('crypto');

const key = 'SECRET_KEY';
const expiry = new Date(new Date().setDate(new Date().getDate()   10)).replace('Z', '0000Z');
const signature = createHmac('sha512', key)
    .update('integration'   '\n'   expiry)
    .digest('base64');
console.log(`SharedAccessSignature uid=integration&ex=${expiry}&sn=${signature}`);
  • Related