3

Here is some Java code that hashes a salted password and prints the first byte to the console. The printed value is 62.

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

class AuthTest
{
    public static void main (String[] args) throws java.lang.Exception
    {
        byte[] result;
        byte[] salt = new byte[] { (byte)0xe3, (byte)0x2c, (byte)0xf8, (byte)0x9e, (byte)0x6f, (byte)0xe4, (byte)0xf8, (byte)0x90 };
        byte[] password = "password".getBytes("UTF-8");

        result = getHash(1105, password, salt);
        System.out.println(result[0]);
    }

    public static byte[] getHash(int iterations, byte[] password, byte[] salt) throws NoSuchAlgorithmException,
        UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.reset();
        md.update(salt);
        byte[] result = md.digest(password);
        for (int i = 0; i < iterations; i++) {
            md.reset();
            result = md.digest(result);
        }
        return result;
    }
}

The following C# code, which I thought was identical to the above, yields the value 40.

void Main()
{
    byte[] salt = new byte[] { (byte)0xe3, (byte)0x2c, (byte)0xf8, (byte)0x9e, (byte)0x6f, (byte)0xe4, (byte)0xf8, (byte)0x90 };
    byte[] password = Encoding.UTF8.GetBytes("password");

    var result = GetHash(1105, password, salt);
    Console.WriteLine(result[0]);
}

public byte[] GetHash(int iterations, byte[] password, byte[] salt)
{
    var saltedPassword = password.Concat(salt).ToArray();
    using (var sha1 = new SHA1CryptoServiceProvider())
    {
        var result = sha1.ComputeHash(saltedPassword);

        for (int i = 0; i < iterations; ++i)
        {
            result = sha1.ComputeHash(result);
        }
        return result;
    }
}

Could someone please help me spot the difference?

2 Answers 2

3

One of the major difference is that in Java, byte is signed while in C#, byte is unsigned. The equivalent for Java byte in C# is sbyte, not byte.

If you want to get the same result as Java in C#, use sbyte for every byte you use in Java.

Sign up to request clarification or add additional context in comments.

1 Comment

IIUC, sbyte vs byte should not make any difference with respect to the hashing algorithm, just the Console output. In this case, even the console output should have been the same.
1

In the Java version you have the salt followed by the password. In the C# version this is reversed.

Comments

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.