What is the equivalent of hashing Java code into C#?



I have a strange problem in getting equivalent hash code from C# code translated into Java. I don’t know, what MessageDigest update method do. It should only update the contents of digest and should compute hash after calling digest.

Same thing I am doing in C# with SHAManaged512.ComputeHash(content). But I am not getting same hash code.

Following is the Java code.

public static String hash(String body, String secret) {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-512");
        md.update(body.getBytes("UTF-8"));

        byte[] bytes = md.digest(secret.getBytes("UTF-8")); 

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

        return sb.toString();
    } catch (Exception e) {
        throw new RuntimeException();
    }
}

Following is C# Code

private byte[] ComputeContentHash(string contentBody)
{               
        using (var shaM = new SHA512Managed())       
        {
            var content = string.Concat(contentBody, Options.SecretKey);

            var hashedValue = shaM.ComputeHash(ToJsonStream(content));
            return hashedValue;
        }
}

public static Stream ToJsonStream(object obj)
{
   return new MemoryStream(Encoding.Unicode.GetBytes(obj.ToString()));
}

Answer

I had the exact same issue. Its been two years since you asked but just in case someone comes across this question, here’s the solution

public static string encryptHash(string APIkey, string RequestBodyJson)
    {
        var secretBytes = Encoding.UTF8.GetBytes(APIkey);
        var saltBytes = Encoding.UTF8.GetBytes(RequestBodyJson);

        using (var sHA256 = new SHA256Managed())
        {
            byte[] bytes = sHA256.ComputeHash(saltBytes.Concat(secretBytes).ToArray());

            //convert to hex
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                builder.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
            }
            return builder.ToString();
        }
    }


Source: stackoverflow