c# equivilant of CryptoJS to create hmacSHA! and convert to Base64

Gerald Oakham 101 Reputation points
2021-12-06T17:35:15.003+00:00

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 :

  1. HTTP verb
  2. Content-MD5 header
  3. Content-Type header
  4. Date
  5. Canonicalized headers
  6. 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#
{count} votes

1 answer

Sort by: Most helpful
  1. Max Helskens 0 Reputation points
    2023-02-01T15:13:18.98+00:00

    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.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.