Export to GitHub

crypto-js - issue #99

CryptoJS SHA256 hash do not match C#/.NET SHA256 hash


Posted on Oct 8, 2013 by Massive Panda

What steps will reproduce the problem? 1. Create a new web application using preferably Visual Studio 2. Paste the code from the attached file as needed into default.ascx.cs file. 3. Complile and run the application to view default.aspx web form.

String to hash: bravo.john2k9@gmail.com

What is the expected output? What do you see instead? Expected: CJ/gIFQ4kB/F8+kk8cDi8TAf731V/mp0rFY162yDckc= Got: HjZp0hFZZRMnNo5JxotoZ9tS5oK7VSfO/pj1Nd/Aq4Y=

What version of the product are you using? On what operating system? 3.1.2

Please provide any additional information below: The hash will be created on server side initially and will be used as needed, though the hash generated on server side shall match the hash generated by CryptoJS.

Comment #1

Posted on Oct 8, 2013 by Happy Horse

The problem is probably rooted in the fact that C#, by default, will convert characters to bytes using UTF-16, and CryptoJS using UTF-8. You'll have to change one or the other so they match.

That being said, there still must be something funky going on in your JS, because neither your expected nor your actual result is the actually expected result for either UTF-16 or UTF-8.

Comment #2

Posted on Oct 8, 2013 by Massive Panda

Thanks Jeff for the quick reply.

I verified my C# output with Hash Generator at http://www.insidepro.com/hashes.php?lang=eng by inputting bravo.john2k9@gmail.com in the password field, and got the following in the fourth field of SHA256 block:

CJ/gIFQ4kB/F8+kk8cDi8TAf731V/mp0rFY162yDckc=

Now based on this, could you provide with the CryptoJS snippet to get UTF-16 result to let me try running the same to match with C# and insidePro results?

Comment #3

Posted on Oct 8, 2013 by Massive Panda

The attached code produces the following output:

.NET SHA256: CJ/gIFQ4kB/F8+kk8cDi8TAf731V/mp0rFY162yDckc=

the uemail cookie is: uemail=bravo.john2k9@gmail.com CryptoJS.SHA256 hash is: 1e3669d21159651327368e49c68b6867db52e682bb5527cefe98f535dfc0ab86 CryptoJS.enc.Base64: HjZp0hFZZRMnNo5JxotoZ9tS5oK7VSfO/pj1Nd/Aq4Y= base64 to word: 1e3669d21159651327368e49c68b6867db52e682bb5527cefe98f535dfc0ab86 CryptoJS.enc.Latin1: 6iÒYe'6ŽIÆ‹hgÛRæ‚»U'Îþ˜õ5ßÀ«† CryptoJS.enc.Hex: 1e3669d21159651327368e49c68b6867db52e682bb5527cefe98f535dfc0ab86

Comment #4

Posted on Oct 8, 2013 by Happy Horse

I verified my C# output with Hash Generator at http://www.insidepro.com/hashes.php?lang=eng by inputting bravo.john2k9@gmail.com in the password field, and got the following in the fourth field of SHA256 block:

The first and second fields are the typically expected value. The third and fourth, according to the site, are "in Unicode." That's not actually helpful, because Unicode could mean UTF-8, or it could mean UTF-16 (either little- or big-endian), or it could mean UTF-32 (either little- or big-endian). Through trial and error, I discovered that it means UTF-16 little-endian.

You should be able to get the same result from CryptoJS if you load the utf16 component and hash the result of:

CryptoJS.enc.Utf16LE.parse("bravo.john2k9@gmail.com")

Comment #5

Posted on Oct 8, 2013 by Massive Panda

Seems like there is some issue in the code below as I am not getting the results you got, could you take a look and point out what's wrong:

<script src='Scripts/jquery-1.8.2.min.js'></script>
<script src='scripts/jquery.cookie.js'></script>
<script src='http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha256.js'></script>;
<script src='http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-utf16-min.js'></script>;

<script>
    $(document).ready(function () {
        var words = CryptoJS.enc.Utf16LE.parse('bravo.john2k9@gmail.com');
        document.write('<br />words: ' + words);
        var hash = CryptoJS.SHA256(words);
        document.write('<br />hash: ' + hash); 
        var encStr = hash.toString(CryptoJS.enc.Utf16LE);
        document.write('<br />encStr: ' + encStr);
        document.write('<br />CryptoJS.enc.Utf16LE.parse(encStr): ' + CryptoJS.enc.Utf16LE.parse(encStr));
        document.write('<br />hash.toString(CryptoJS.enc.Latin1): ' + hash.toString(CryptoJS.enc.Latin1));
        document.write('<br />hash.toString(CryptoJS.enc.Hex): ' + hash.toString(CryptoJS.enc.Hex));
    });

Output:

words: 62007200610076006f002e006a006f0068006e0032006b003900400067006d00610069006c002e0063006f006d00 hash: 089fe0205438901fc5f3e924f1c0e2f1301fef7d55fe6a74ac5635eb6c837247 encStr: 鼈⃠㡔ᾐⓩ샱ἰ緯﹕瑪嚬荬䝲 CryptoJS.enc.Utf16LE.parse(encStr): 089fe0205438901fc5f3e924f1c0e2f1301fef7d55fe6a74ac5635eb6c837247 hash.toString(CryptoJS.enc.Latin1): Ÿà T8Åóé$ñÀâñ0ï}Uþjt¬V5ëlƒrG hash.toString(CryptoJS.enc.Hex): 089fe0205438901fc5f3e924f1c0e2f1301fef7d55fe6a74ac5635eb6c837247

Comment #6

Posted on Oct 8, 2013 by Happy Horse

I'm not sure why you think anything is wrong. The hex hash value you get is the same as what insidepro.com gives you: 089fe0205438901fc5f3e924f1c0e2f1301fef7d55fe6a74ac5635eb6c837247

Comment #7

Posted on Oct 8, 2013 by Massive Panda

Thanks Jeff. I was trying to get CJ/gIFQ4kB/F8+kk8cDi8TAf731V/mp0rFY162yDckc=, is there a way to get this value using the hash above?

Comment #8

Posted on Oct 8, 2013 by Happy Horse

That's a base64 result, so...

hash.toString(CryptoJS.enc.Base64)

(Make sure you've loaded the base64 component.)

Comment #9

Posted on Oct 9, 2013 by Massive Panda

Thanks a lot Jeff. I got both UTF 8 and UTF16 working.

I have attached sample VS2012 C#.NET projects for reference, error handling, and code optimization is not done.

Attachments

Comment #10

Posted on Oct 10, 2013 by Happy Horse

(No comment was entered for this change.)

Status: Invalid

Labels:
Type-Defect Priority-Medium