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?
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));
const signature = createHmac('sha512', key)
.update('integration' + '\n' + expiry.toJSON().replace('Z', '0000Z'))
.digest('base64');
console.log(`SharedAccessSignature uid=integration&ex=${expiry.toJSON().replace('Z', '0000Z')}&sn=${signature}`);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.