Что эквивалентно хешированию Java-кода в C#?

У меня странная проблема с получением эквивалентного хеш-кода из кода C#, переведенного на Java. Я не знаю, что делает метод обновления MessageDigest. Он должен обновлять только содержимое дайджеста и вычислять хеш после вызова дайджеста.

То же самое я делаю в C# с SHAManaged512.ComputeHash(content). Но я не получаю тот же хэш-код.

Ниже приведен код Java.

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();
    }
}

Ниже приведен код C#

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()));
}

2 ответа

Решением было поставить первый секретный ключ и дополнить его данными о полезной нагрузке.

У меня была такая же проблема. Прошло два года с тех пор, как вы спросили, но на случай, если кто-то столкнется с этим вопросом, вот решение

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();
        }
    }

Encoding.Unicode (который вы используете в C# ToJsonStream метод) не является UTF8. Это UTF16. Смотрите MSDN. (Также имейте в виду, что UTF16 может иметь младший или младший порядковый номер.) Вы ищете Encoding.UTF8,

Первое, что нужно сделать, это проверить, совпадает ли байтовый массив, который вы хэшируете.

Другие вопросы по тегам