The following C# code creates the hash that I need to generate in a POSTMAN Pre-Request Script so that it can be added to the sent message.
using (HMACSHA1 hmac = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(KeyString)))
{
hash = Convert.ToBase64String( hmac.ComputeHash(ASCIIEncoding.ASCII.GetBytes(StringToHash)));
}
The KeyString and StringToHash are being created correctly, but the signature generated from the code below is not matching.
var signature = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA1(CryptoJS.enc.Hex.parse(StringToHash),CryptoJS.enc.Hex.parse(KeyString)));
Questions:
I think the CryptoJS.enc.Base64.stringify is correct and the CryptoJS.HmacSHA1 is likely alright, but how do I create the equivalent ASCII encoded byte arrays?
Can I link a simple C# .dll into POSTMAN to do the hashing in C#?
I could not find any documentation for the POSTMAN OAUTH helper, would it “help” in this case?
It looks like you’re using ASCII-encoding for the key and message in the C# example, while you’re hex-encoding the key and message in the CryptoJS example.
You can change your CryptoJS code to look something like this, and it should start working:
I will give it a shot, but I am not hopeful. The C# call to ASCIIEncoding.ASCII.GetBytes, converts the string to a Byte Array, I don’t think a simple string will do the trick, but I can easily try.
Weird. The fix I proposed works for me when I test with both C# and CryptoJS.
Don’t worry about bytes vs. string. CryptoJS, by default, will encode as UTF-8 bytes. If your key and message are valid ASCII, the ASCII vs UTF-8 difference shouldn’t have an impact, either. But perhaps if they’re not valid ASCII, the conversion on the C# side could be off? You could try using UTF8Encoding.UTF8.GetBytes on the C# side.
In that case, you’ll have to modify the JavaScript to replace the non-ASCII characters with a question mark (?), which is what the .NET library will do. To verify, here’s my Program.cs.
using System;
using System.Security.Cryptography;
using System.Text;
namespace shatest
{
class Program
{
static void Main()
{
var key = "keystring";
var message = "stringtohashÝŁ";
using (HMACSHA1 hmac = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(key)))
{
var hash = Convert.ToBase64String( hmac.ComputeHash(ASCIIEncoding.ASCII.GetBytes(message)));
Console.WriteLine(hash);
}
}
}
}
Notice the convertToAscii function. You’ll need this for compatibility. But really, there’s going to be a lingering problem here that should get addressed down the road. The C# side should be using a character encoding that supports the input.
The return from convertToAscii(m) should be a Byte Array not a string. By default Bytes Arrays in C# are unsigned, so the code should read something like
But I really have not had time to look at it today, other than to confirm that it did not match with the code as originally provided…Caveat, I did not look all that hard at it…no time today.
CryptoJS does the conversion internally. If you get this to work, I wouldn’t anticipate a different result. Each ASCII character is going to be a single byte represented by an unsigned 8-bit integer. A string of valid ASCII characters will get translated into an equivalent byte array by CryptoJS. The abstraction provided by CryptoJS means we don’t have to do this ourselves.
If this is still not working after following the advice previously given, please create a minimal reproduction that demonstrates the problem, and I’ll be happy to continue efforts!