5

I have an algorithm in C# running on server side which hashes a base64-encoded string.

byte[] salt = Convert.FromBase64String(serverSalt); // Step 1
SHA256Managed sha256 = new SHA256Managed(); // Step 2
byte[] hash = sha256.ComputeHash(salt); // Step 3
Echo("String b64: " + Convert.ToBase64String(hash)); // Step 4

The hash is then checked against a database list of hashes. I'd love to achieve the same with javascript, using the serverSalt as it is transmitted from C# through a websocket.

I know SHA-256 hashes different between C# and Javascript because C# and Javascript have different string encodings. But I know I can pad zeros in the byte array to make Javascript behave as C# (step 1 above is solved).

var newSalt  = getByteArrayFromCSharpString(salt); // Pad zeros where needed
function getByteArrayFromCSharpString(inString)
{
  var bytes = [];
  for (var i = 0; i < inString.length; ++i)
{
    bytes.push(inString.charCodeAt(i));
    bytes.push(0);
}
return bytes;
}

Could anyone provide some insight on which algorithms I could use to reproduce steps 2, 3 and 4?

PS: there are already questions and answers around but not a single code snippet.

6
  • "I know that a byte array from C# and Javascript will be different" That's not true when working with binary data/base64. The only difference is the default conversion between string and bytes. Just use UTF-8 or UTF-16 for both, don't pad with zeros. Commented Dec 11, 2012 at 13:06
  • "I know that a byte array from C# and Javascript will be different" was in my original question, which was edited seconds later :) You're quite quick! What I meant is that same string in C# and Javascript will produce different byte arrays. Once the byte array is the same in both (step1), the algorithms (step2) should produce the same hashed byte array (step3). Then, I can convert both to base64 (step4). I'd love some insight on steps 2-4, there are many suggestions around but no code to speak of. Commented Dec 11, 2012 at 14:34
  • 1
    When using base64, the conversion from string to bytes is the same for both C# and Javascript. The difference you're talking about only applies to text, and even then it's broken. Commented Dec 11, 2012 at 14:43
  • Thanks CodesInChaos, I managed to sort it out and you are absolutely right about the b64 <-> bytes conversion: it is the same in C# and Javascript Commented Dec 13, 2012 at 10:41
  • "This is very suitable for secure client-server communication of hashed credentials" communication of hashed credentials is usually a bad approach that doesn't improve security over plaintext communication, and sometimes even decreases it. But without details I can't tell you much, only that no such scheme can replace SSL for webapplications. Use SSL. Commented Dec 13, 2012 at 10:56

2 Answers 2

7

Here's the solution, I really hope this could help other people in the same situation.

In the html file, load crypto-js library

<!-- library for doing password hashing, base64 eoncoding / decoding -->
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/core-min.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/enc-base64-min.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha256.js"></script>

In the javascript, do the following

// This function takes a base64 string, hashes it with the SHA256 algorithm
// and returns a base64 string. 
function hashBase64StringAndReturnBase64String(str)
{
    // Take the base64 string and parse it into a javascript variable
    var words  = CryptoJS.enc.Base64.parse(str);
    // Create the hash using the CryptoJS implementation of the SHA256 algorithm
    var hash = CryptoJS.SHA256(words);
    var outString =  hash.toString(CryptoJS.enc.Base64)
    // Display what you just got and return it
    console.log("Output string is: " + outString);
    return outString;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, malber. All those Google links go to 404s now. I'm trying to find the new URLs but am having problems. If anyone else knows what they are, I'd sure appreciate it.
I tried using your code snippet but I am getting CryptoJS is not defined error. What could be the reason ?
cryptoJS probably moved elsewhere
0

check Java script SHA256 implementation on the following URL http://www.movable-type.co.uk/scripts/sha256.html

1 Comment

Thank you Saddam. I already looked at that URL and I get the same result as using CryptoJS, i.e. var hash = CryptoJS.SHA256(stringToHash); console.log("b64 " + hash.toString(CryptoJS.enc.Base64)); The resulting string, however, does not match the one obtained with C#. My fear is that both algorithms rely on an input string: given that I need to pad zeros to the byte array obtained with the original string, I'd rather work with bytes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.