7

I have the following code in C#

var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ==";
var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ=";

var key = Convert.FromBase64String(apiSecret);
var provider = new System.Security.Cryptography.HMACSHA256(key);

var hash = provider.ComputeHash(Encoding.UTF8.GetBytes(apiKey));
var signature = Convert.ToBase64String(hash);

I am trying to get the same result in Javascript using the CryptJS library but from what i can tell i am not converting the key and secret to byte arrays and the encoding is incorrect. first try looks like:

var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ==";
var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ=";
var hash = CryptoJS.HmacSHA256(apiKey, apiSecret);
var sig = hash.toString(CryptoJS.enc.Base64);
billy jean
  • 1,399
  • 4
  • 25
  • 45
  • 2
    Read the code that you've posted here again. You forgot to parse the Base64-encoded `apiSecret` in CryptoJS. Even worse, you forgot to pass `apiKey` and `apiSecret` to `CryptoJS.HmacSHA256` entirely. – Artjom B. Aug 12 '16 at 22:27
  • It was a quick cut and paste of the original code from the CryptoJS docs. Passing the correct values still doesn't fix it but thanks for pointing that out. Do you have any actual insight into making it work? – billy jean Aug 13 '16 at 15:17
  • 1
    Yes, I have actual insight which I already shared with you. You already should have the tools to make it work. Do you have trouble parsing the Base64-encoded string with CryptoJS? If not, have you exchanged the order of the arguments to `CryptoJS.HmacSHA256`? – Artjom B. Aug 13 '16 at 15:38
  • Why not add the answer then i can mark it as accepted and other people can benefit from the correct answer? I appreciate your help.. just not following your response. – billy jean Aug 13 '16 at 16:47
  • Currently, you're passing the literal string `"apiKey"` rather than the *variable* `apiKey` to the HmacSHA256 function. – Heretic Monkey Aug 16 '16 at 18:42
  • Sorry. Updated. The example JS is far from the correct answer. Ultimately I'm looking for someone to provide a complete JS solution that gives the same signature value in JS as the C# provided. – billy jean Aug 16 '16 at 19:01
  • @billyjean Your javascript is actually very close, the only thing missing is the encoding part. – John Siu Aug 17 '16 at 04:41

1 Answers1

21

Inspire by https://stackoverflow.com/a/13837543/1810391

Javascript

var CryptoJS = require('crypto-js');

var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ==";
var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ=";

// var key = Convert.FromBase64String(apiSecret);
var key = CryptoJS.enc.Base64.parse(apiSecret);
console.log('key:' + key);

// var prehash = Encoding.UTF8.GetBytes(apiKey);
var prehash = CryptoJS.enc.Utf8.parse(apiKey);
console.log('Pre-hash:' + prehash);

// var provider = new System.Security.Cryptography.HMACSHA256(key);
// var hash = provider.ComputeHash(prehash);
var hash = CryptoJS.HmacSHA256(prehash, key);
console.log('hash:' + hash);

//var signature = Convert.ToBase64String(hash);
var signature = hash.toString(CryptoJS.enc.Base64);
console.log('signature:' + signature);

Javascript Output

key:41a4d6df195fd54e658dd940252765b734fbd5f145f9e6
Pre-hash:53424233615778734947316861325567625862635156424a49484e7c593356795a513d3d
hash:ecb6cdf5dd39872bb2cbce4321e2725e11b99c01af9c2a620ebbaf3d8d8607e7
signature:7LbN9d05hyuyy85DIeJyXhG5nAGvnCpiDruvPY2GB+c= 

C#

using System;
using System.Text;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var apiKey = "SBB3aWxsIG1ha2UgbXbcQVBJIHN|Y3VyZQ==";
            var apiSecret = "QaTW3xlf1U5ljdlAJSdltzT71fFF+eZ=";
            var key = Convert.FromBase64String(apiSecret);
            Console.Write("key:");
            prtByte(key);

            Console.Write("Pre-hash:");
            prtByte(Encoding.UTF8.GetBytes(apiKey));
            var provider = new System.Security.Cryptography.HMACSHA256(key);
            var hash = provider.ComputeHash(Encoding.UTF8.GetBytes(apiKey));
            Console.Write("hash:");
            prtByte(hash);

            var signature = Convert.ToBase64String(hash);
            Console.WriteLine("signature:" + signature);
        }
        public static void prtByte(byte[] b)
        {
            for (var i = 0; i < b.Length; i++)
            {
                Console.Write(b[i].ToString("x2"));
            }
            Console.WriteLine();
        }
    }
}

C# Output

key:41a4d6df195fd54e658dd940252765b734fbd5f145f9e6
Pre-hash:53424233615778734947316861325567625862635156424a49484e7c593356795a513d3d
hash:ecb6cdf5dd39872bb2cbce4321e2725e11b99c01af9c2a620ebbaf3d8d8607e7
signature:7LbN9d05hyuyy85DIeJyXhG5nAGvnCpiDruvPY2GB+c=
Community
  • 1
  • 1
John Siu
  • 5,056
  • 2
  • 26
  • 47
  • Hi John, thank you very much for taking the time. I really appreciate it. The problem here is my original C# is correct and i need the JS to compute the same signature as the C# i provided. The signature looks like UufyTxE87/MsjPkLVBBm39G5H1O4bnMj17qSXqyO2/0= . Maybe you are close? Again thanks for taking the time. Not sure why people are downvoting this. – billy jean Aug 19 '16 at 17:22
  • 1
    @billyjean My C# is actually your code, the only changes are all the `Console.Write`. I tested on windows 10 and os x boxes and both c# and js give same result. Are you using the same `apiKey` and `apiSecret` you posted in the question? – John Siu Aug 19 '16 at 18:46
  • John you were absolutely right. Sorry for the confusion. I just went through your code again, implemented it into my solution and retried and everything is working. Thanks so much. Wish i had more to send than rep. Again not sure why this is downvoted. This is the only complete solution to this issue. Which is an issue for everyone attempting to connect to a .Net API with JS requiring using this security scheme. – billy jean Aug 19 '16 at 21:26
  • 1
    @billyjean I can only rescue you one vote, lol. And I agree about the issue using different crypto package on different languages and try to have them work together. I tried so many different ways and JS packages, but cannot make it right till I see someone else example. Open source is good, just many times doc is inadequate and good sample is difficult to come by. – John Siu Aug 19 '16 at 23:31