SHA256 Behave Differently In c#

I need to pass a SHA256 hash to some 3rd party API. They have even provided a sample in JS which works fine and the results is matched with online SHA256 generator like this one:

But the problem occurs when I use C# to generate the SHA256 hash.

I’ve matched almost everything like input, encoding; etc.
But I’m not exactly sure what the issue actually.

Please check the input which behave differently below

Input

{
  "correlation_identifier": "Payee Validation",
  "context": "PAYM",
  "creditor_account": "23124812341",
  "creditor_name": "NARUMATT",
  "uetr": "3c9e595f-07d8-4f56-ae80-8edbb7683d59",
  "creditor_agent": {
    "bicfi": "BSALSVSS"
  }
}

Online Results

a425b580c44e2c3ba6ce213529818feea5bd7ccfd76ccd02171c87ff1e53c8ee

C# Results

b192e9203176649de967fa4cbe9e513a77fc29797981ea1ce93e6e07e5dd94e3

c# Code

       string inputString = JsonConvert.SerializeObject(new Input()
            {
                correlation_identifier = "Payee Validation",
                context = "PAYM",
                creditor_account = "23124812341",
                creditor_name = "NARUMATT",
                uetr = "3c9e595f-07d8-4f56-ae80-8edbb7683d59",
                creditor_agent = new CreditorAgent()
                {
                    bicfi = "BSALSVSS"
                }

            }, Formatting.Indented);

       string base64Hash = GenerateSha256(inputString);
       static string GenerateSha256(string inputString)
            {
    
                var hash = new System.Text.StringBuilder();
                using (SHA256 sha256 = SHA256.Create())
                {
                    byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(inputString));
    
                    foreach (byte theByte in hashBytes)
                    {
                        hash.Append(theByte.ToString("x2"));
                    }
    
                }
                return hash.ToString();
            }
    

JS Sample

var CryptoJS = require('crypto-js')
var reqBodyUtf8 = CryptoJS.enc.Utf8.parse(pm.request.body.raw);
var reqBodyDigest = CryptoJS.SHA256(reqBodyUtf8).toString(CryptoJS.enc.Base64);

  • Please show the js code sample

    – 

  • 2

    Hashing doesn’t behave differently in C#. In all the duplicate questions (and there are several) the content wasn’t the same. Hashing treats whitespace the same as Spaces, indentation and newlines matter. What is the exact string you used in the C# code? I bet it’s not what’s posted here

    – 

  • 1

    @MuhammadFaisal i am reading it from text file all the more reason to assume it’s NOT the same, because newlines will be different, indenting may use tabs or whitespace. Remove whitespace before calculating the hash

    – 

  • 2

    No repro. When I use the question’s JSON string in this fiddle I get the exact same hash as the “online” converter: a425b580c44e2c3ba6ce213529818feea5bd7ccfd76ccd02171c87ff1e53c8ee

    – 




  • 3

    Same code but different data. We already explained what’s going on. The newlines and spaces are different. On Windows machines a newline is two characters \r\n while on Linux it’s one \n. If you copy the string you posted here into your code instead of loading it from a file you’ll see the hashes are identical

    – 

Leave a Comment