.net - HMACSHA256.ComputeHash - Unexpected Result


I'm trying to generate a signature in VB.NET using the following vendor documentation as a reference guide:


They also provide this sample JS code:


I'm having trouble getting the correct result from the 2nd time I do HMACSHA256.ComputeHash. I think it has something to do with the way I generate the 'stringToSign', but I'm out of ideas at this point. Any help would be greatly appreciated!

Public Shared Function GenerateSignature() As String
    Dim encoding = New System.Text.UTF8Encoding()
    'Dim encoding = New System.Text.ASCIIEncoding()
    'Dim encoding = New System.Text.UnicodeEncoding()

    Dim registrationKey = "2e751ce9-5684-4925-9cc3-0665802ebc55"
    Dim requestTimestamp = "2015-01-20T01:07:18.763Z"
    Dim stringToSign = "2015-01-20T01:07:18.763Z\nhttps://submit-portal.mediashuttle.com/metadata/v3.0/portal/submit-portal/package/4eMv\nX-Sig-Algorithm%3dSIG1-HMAC-SHA256&X-Sig-Date%3d2015-01-20T01%3a07%3a18.763Z\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    'Dim stringToSign As String = requestTimestamp + "\r\n" + requestUrl + "\r\n" + canonicalQueryString + "\r\n" + requestBodyHash
    'Dim stringToSign As String = requestTimestamp + Environment.NewLine + requestUrl + Environment.NewLine + canonicalQueryString + Environment.NewLine + requestBodyHash

    ' Generate the signing key
    Dim signingKey As Byte()
    Using HMACSHA256 As New System.Security.Cryptography.HMACSHA256(encoding.GetBytes(registrationKey))
        signingKey = HMACSHA256.ComputeHash(encoding.GetBytes(requestTimestamp))
    End Using
    Dim signingKeyString = Replace(BitConverter.ToString(signingKey), "-", "").ToLower()
    Console.Write("signingKeyString: '" + signingKeyString + "'" + Environment.NewLine + Environment.NewLine)

    ' RESULT OK: 'ebf870730d4d914fd8c24761433524171e948cd851830e785343b5f9d0d0f56a'

    ' Generate request signature
    Dim signature As Byte()
    Using HMACSHA256 As New System.Security.Cryptography.HMACSHA256(signingKey)
        signature = HMACSHA256.ComputeHash(encoding.GetBytes(stringToSign))
    End Using
    Dim signatureString = Replace(BitConverter.ToString(signature), "-", "").ToLower()
    Console.Write("signatureString: '" + signatureString + "'" + Environment.NewLine + Environment.NewLine)

    ' RESULT BAD: '5f0b42c5cebf1158d9154586522489884fb642b6e7cc544aff8fa79e4f2c5a57'
    ' According to reference doc, should be: '139319aec19208168aaea515d0110b75d36c73de852c3265fc9758834d1b78ec'

    Return signatureString
End Function

1 Answer: 

Turns out the problem involved multiple issues:

  1. New line seperator needed to be ChrW(10). Thanks Hans Passant!
  2. Url Encoding of the original components in the stringToSign needed to use uppercase characters.
  3. Encoding needed to be UTF8.

My working function:

Imports Rework '3rd Party Library: https://www.nuget.org/packages/Rework/
Imports System.Web
Imports System.Text
Imports System.Text.RegularExpressions

Public Class Signiant
Public Shared Function GenerateSignedUrl(requestUrl, requestBody, registrationKey) As String
    Dim requestTimestamp = DateTime.UtcNow.ToString("o")

    requestUrl = "https://submit-portal.mediashuttle.com/metadata/v3.0/portal/submit-portal/package/4eMv"
    requestBody = ""
    registrationKey = "2e751ce9-5684-4925-9cc3-0665802ebc55"
    requestTimestamp = "2015-01-20T01:07:18.763Z"

    ' Generate canonical query String
    Dim algorithmParam = "X-Sig-Algorithm=SIG1-HMAC-SHA256"
    Dim dateParam = "X-Sig-Date=" + requestTimestamp
    Dim canonicalQueryString = HttpUtility.UrlEncode(algorithmParam) + "&" + HttpUtility.UrlEncode(dateParam)
    canonicalQueryString = Regex.Replace(canonicalQueryString, "(%[0-9a-f][0-9a-f])", Function(c) c.Value.ToUpper())

    ' Generate the string to sign
    Dim requestBodyHash = Crypto.ToSHA(requestBody, Crypto.SHA_Type.SHA256).ToLower()
    Dim stringToSign As String = requestTimestamp + ChrW(10) + requestUrl + ChrW(10) + canonicalQueryString + ChrW(10) + requestBodyHash

    ' Generate the signing key
    Dim signingKey As Byte()
    Using HMACSHA256 As New System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(registrationKey))
        signingKey = HMACSHA256.ComputeHash(Encoding.UTF8.GetBytes(requestTimestamp))
    End Using

    ' Generate request signature
    Dim signature As Byte()
    Using HMACSHA256 As New System.Security.Cryptography.HMACSHA256(signingKey)
        signature = HMACSHA256.ComputeHash(Encoding.UTF8.GetBytes(stringToSign))
    End Using
    Dim signatureHex = Replace(BitConverter.ToString(signature), "-", "").ToLower()

    ' Generate the signed URL
    Dim signatureParam = "X-Sig-Signature=" + signatureHex
    Dim signedUrl = requestUrl + "?" + algorithmParam + "&" + dateParam + "&" + signatureParam

    Return signedUrl
End Function
End Class

More Articles

regex - Regular expressions in R: pattern repetitions with {}

I am having trouble with a regular expression in R. The goal is to parse a Markdown/reST/knitr report text file in R to remove my own custom comments. These comments are put in the following form: Some sentence is about something <find a citation to this>.As Markdown uses <> for HTML tags,

android - Mock Location permission issue on release app

I developed Fake GPS application and all my codes work nicely on debug mode.When i try "mock location" on **release version**, i got this error;java.lang.SecurityException: Requires `ACCESS_MOCK_LOCATION` permissionI already had ACCESS_MOCK_LOCATION in debug/AndroidManifest file.<uses-permission

android - Why getLastKnownLocation(provider) doesn't return null after clearTestProviderLocation(provider)

I was assuming that getLastKnownLocation does return null for a given provider after calling clearTestProviderLocation for same provider.Why ? because documentation says for clearTestProviderLocation; Removes any mock location associated with the given provider.public void test() throws SecurityExc

php - Key for HMAC Algorithm

How to generate the secret key for the HMAC algorithm as I have to use it for data verification at the other clients end?Thanks in advance.

How do I cross-compile a Linux kernel to a MIPS little endian host?

The kernel in question is 2.6.18. If I callmake ARCH=mips CROSS_COMPILE=mipsel-linux- menuconfigthere will be only the option to build a big endian kernel in the menu. If I use ARCH=mipsel, it will complain about not having an arch/mipsel dir.How's this done?

r - adding two column of a data where col1 contains date and col2 contains days

I have a data frame in which i have two columns date and days and i want to add date column with days and show the result in other column data frame-1col date is in format of mm/dd/yyyy formatdate days3/2/2019 83/5/2019 43/6/2019 43/21/2019 33/25/2019 7and i want my output like t

parsing - How to parse an array of json object using jq

I need to parse a Json file which have a lot of arrays. This is the json source:{"iabVersion": "IAB_V2","categories": [{ "categories": [{ "categories": [{ "id": "1.1.1", "name": "Commercial Trucks" }, { "id": "1.1.2", "name": "Conve

android - Exception while instantiating MockRunner- [NoSuchMethodError] [Kotlin]

I have created a library for distribution the network requests amongst different clients. I am using OkHttp3 in one of the clients. For testing my library, I am trying to mock the response using the okhttp3.mockwebserver. The way I am trying to set up my mock web server is as follows:val server = Mo

C++/C#/Java video analysis question

Could someone give references / frameworks, which allow to do something like Microsoft Kinect does, but using only one video stream?I would like to see algorithm abstracts and papers if there are some (I hope there are).If somebody had practical experience of using them, please share it :)

Streaming opencv Video

I need some ideas about how to stream video feed coming from opencv to a webpage. I currently have gStreamer, but I don't know if this is the right tool for the job. Any advice on using gStreamer or any hyperlinks to tutorials would be helpful and appreciated!Thanks!