Did you manage to find a solution? I have the same problem.
Hashing works fine in postman, but I get a different result from my C# code.
c# equivilant of CryptoJS to create hmacSHA! and convert to Base64

HI,
Firstly, apologies for the lengthy post , I am just trying to present all the information I have to help out.
I am trying (without any luck) to create some values for an API POST.
When I use the API environment within POSTMAN (which uses " CryptoJS.HmacSHA1" and "CryptoJS.enc.Base64.stringify"), it works fine.
When I try outside of postman (using the code Snipped from it), i Get :
The signature of the request did not match calculated signature
... so.. I am obviously doing something different, I just can't see what.
One of the header Titles is "Content-MD5", and its value needs to be "the MD5 digest of the request body encoded as Base64. It is terminated by a line feed character."
So I have taken the Body of the request (aka)
var Cutbody = @"{" + "\n"
+ @"""expireTime"": ""20211125T1210""," + "\n"
+ @"""format"": ""rfid48""," + "\n"
+ @"""doorOperations"": [ { ""operation"": ""guest"", ""doors"": [""001""] } ]"+ "\n"
+ @"}"
+ "\n" + @"";
and the done this
//convert body into md5hash (hex)
string hash2 = CreateMD5Hash(Cutbody);
// convert md5 hash in Base64
string base64hash2 = ConvertHexStringToBase64(hash2);
where the definitions are:
/// Converts "input" aka requests "body" into a MD5Hash
public static string CreateMD5Hash(string input)
{
// Step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
return sb.ToString();
}
and
/// Converts "hexString" aka MD5Hash into Base64
public static string ConvertHexStringToBase64(string hexString)
{
byte[] buffer = new byte[hexString.Length / 2];
for (int i = 0; i < hexString.Length; i++)
{
buffer[i / 2] = Convert.ToByte(Convert.ToInt32(hexString.Substring(i, 2), 16));
i += 1;
}
string res = Convert.ToBase64String(buffer);
return res;
}
I then need to create a "signature" (which is used as part of an authorization field), which is done by building up a string comprising of 6 elements :
- HTTP verb
- Content-MD5 header
- Content-Type header
- Date
- Canonicalized headers
- Canonicalized resource
so...
//// build string to sign
var string_to_sign = "POST" + "\n";
string_to_sign += base64hash2 + "\n";
string_to_sign += "application/json;charset=utf-8" + "\n";
string_to_sign += "\n";
string_to_sign += "x-aah-date:" + curntdateStr + rgn + "\n";
string_to_sign += "/api/v2/crds?action=encoders&encodeme=devicename";
where curntdateStr = date.ToString("ddd, dd MMM yyyy HH:mm:ss ") and Rgn = "GMT".
so, either by encoding routines are wrong, or the data I am passing is incorrect.
Do the CreateMD5Hash and ConvertHexStringToBase64 procedures produce the same output that CyrptoJS does? Am I using them in the wrong way, or is there an easier / better way of a) getting the MD5 for the request body encoded as Base64, and the HmacSHA1 (and converting this into base64) for the "string_to_sign" string?
Thanks in advance.
Developer technologies | C#
1 answer
Sort by: Most helpful
-
Max Helskens 0 Reputation points
2023-02-01T15:13:18.98+00:00