Question

I need to be able to produce a hash value in javascript that will match on the server.

These are the sample input:

string plaintext = "1398836885";
string salt = "8xTpd9gMxF22nBcotVChIH5ocxplLQzI3Ba7xXBkMyyOVVr6e5/mupqxFHYVQD0U77BEbQ9auMWglUK63PeqCX4eB8kzBoOEAr1nXqpT3jjNwdYPQPdRvwPjdI/357CP";

the correct hash result is:

ovsvdWYOUIXU+LAfIYtOf7N60v6Qap6qBgS3IVwBG6k=  

The code for getting plaintext is:

var now = ((long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();  

And the code that Generates the correct hash:

Usage:

var _hash = Hashbrowns.Hash(plaintext, salt);  

Code:

public static class Hashbrowns
{
    private const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";

    public static string Hash(string plaintext, string salt = null)
    {
        return Hashbrowns.Hash<SHA256Cng>(plaintext, salt);
    }

    public static string Hash<TAlgorithm>(string plaintext, string salt = null) where TAlgorithm : HashAlgorithm, new()
    {
        var algorithm = Activator.CreateInstance<TAlgorithm>();

        if (string.IsNullOrWhiteSpace(salt))
        {
            salt = Config.Salt;
        }

        var data = Encoding.UTF8.GetBytes(plaintext + salt);
        return Convert.ToBase64String(algorithm.ComputeHash(data));
    }

    public static string HashPassword(string value)
    {
        return Hash(value, Config.Salt + Config.Spice);
    }

    public static string RandomString(int length)
    {
        var random = new Random();
        return new string(
            Enumerable
                .Repeat(Hashbrowns.chars, length)
                .Select(o => o[random.Next(o.Length)])
                .ToArray()
            );
    }
}  

JAVASCRIPT PART
In my javascript code, I use Crypto Js to get SHA256:

<script type="text/javascript" src="plugin/CryptoJS v3.1.2/rollups/sha256.js"></script>  

Hash: function(){

    var o = "13988354648xTpd9gMxF22nBcotVChIH5ocxplLQzI3Ba7xXBkMyyOVVr6e5/mupqxFHYVQD0U77BEbQ9auMWglUK63PeqCX4eB8kzBoOEAr1nXqpT3jjNwdYPQPdRvwPjdI/357CP",
            hash256 = CryptoJS.SHA256(o),           
        ;

    console.log(hash256.toString(CryptoJS.enc.Base64)); 

}  

And the result is:

a2fb2f75660e5085d4f8b01f218b4e7fb37ad2fe906a9eaa0604b7215c011ba9  

Obviously, they are not the same.

Luckily, there was a version of JAVA code, that can produce same result. I just got this code from outsource developer, and I'm telling you, I'm not so familiar with JAVA.

StringBuilder sb = new StringBuilder();

    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.reset();
    byte[] buffer = hash.getBytes("UTF-8");
    md.update(buffer);
    byte[] digest = md.digest();

    for (int i  = 0; i < digest.length; i++){
      sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
    }

    hashKey = Base64.encodeToString(digest, Base64.DEFAULT);

}

They said that they were able to get the correct result using this code. And if this code is possible to convert into javascript code, this may solved the problem.

BTW, this code is part of a simple mobile app (html base) that will be published using PhoneGap. There is no API on the server that I can use to produce hash.

Was it helpful?

Solution

The hashing part is actually working fine - you're getting the same binary data in both cases - the only difference is that your output in the Javascript is in hex, rather than base64. This C# code:

using System;

class Test
{
    static void Main()
    {
        string base64 = "ovsvdWYOUIXU+LAfIYtOf7N60v6Qap6qBgS3IVwBG6k=";
        byte[] rawData = Convert.FromBase64(base64);
        Console.WriteLine(BitConverter.ToString(rawData));
    }
}

... prints out:

A2-FB-2F-75-66-0E-50-85-D4-F8-B0-1F-21-8B-4E-7F-B3-7A-D2-FE-90-6A-9E-AA-06-04-B7-21-5C-01-1B-A9

That's the same as your Javascript output, modulo casing and the "-" between bytes.

Having just tried this myself with Crypto-js, I think the problem is that you don't have the enc-base64.js component, which isn't included in the rollup. Just add:

<script type="text/javascript" src="plugin/CryptoJS v3.1.2/components/enc-base64.js"></script>

... and everything should be okay. (Check that you've got that file, of course...)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top