Расчет хэшей SHA-1 в Java и C # - PullRequest
6 голосов
/ 27 июля 2011

Расчет хэшей SHA-1 в Java и C #

Я пытаюсь повторить логику Java-приложения в приложении C #.Часть этого включает генерацию хэша пароля SHA-1.К сожалению, я не могу получить те же результаты от Java и C #.

C# Output  : 64  0a  b2 ba e0 7b  ed c4 c1 63  f6 79  a7 46  f7 ab 7f  b5 d1 fa
Java Output: 164 10a b2 ba e0 17b ed c4 c1 163 f6 179 a7 146 f7 ab 17f b5 d1 fa 

Чтобы попытаться выяснить, что происходит, я использую отладчик в Eclipse и Visual Studio.

1. Check values of byte[] key:

    Java: { 84, 101, 115, 116 }
    C#  : { 84, 101, 115, 116 }

2. Check value of byte[] hash:

    Java: { 100 10 -78 -70 -32 123 ... }
    C#  : { 100 10  78 186 224 123 ... }

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

Спасибо,

Карле


Версия Java:

public void testHash() {

    String password = "Test";

    byte[] key = password.getBytes();

    MessageDigest md = MessageDigest.getInstance("SHA-1");

    byte[] hash = md.digest(key);

    String result = "";
    for ( byte b : hash ) {
        result += Integer.toHexString(b + 256) + " ";
    }

    System.out.println(result);

}

Версия C #:

public void testHash() {

    String password = "Test";

    byte[] key = System.Text.Encoding.Default.GetBytes(password);

    SHA1 sha1 = SHA1Managed.Create();

    byte[] hash = sha1.ComputeHash(key);

    String result;
    foreach ( byte b in hash ) {
        result += Convert.ToInt32(b).ToString("x2") + " ";
    }

    Console.WriteLine(result);

}

Ответы [ 2 ]

13 голосов
/ 27 июля 2011

В версии Java не используйте b + 256; вместо этого используйте b & 255. С частью SHA-1 все в порядке, это всего лишь вопрос печати выходных данных. Тип Java "byte" подписан: он возвращает значения в диапазоне от -128 до 127. Чтобы получить соответствующее значение без знака, вы должны добавлять 256 , только если значение отрицательное.

Побитовое И с 255 (это то, что делает "& 255"), выполняет правильное преобразование, которое на двоичном уровне является усечением значения до его 8 младших значащих бит.

0 голосов
/ 30 декабря 2014

Ваш вопрос и ответ были очень полезны для меня, но я заметил, что когда пароль имеет символ «0», сгенерированные хэш-коды различаются, поэтому я немного изменил код (на Java).

for (int i = 0; i < hash.length; i++)
    {
        String hex = Integer.toHexString(hash[i]);
        if (hex.length() == 1) hex = "0" + hex;
        hex = hex.substring(hex.length() - 2);
        result += hex;
    }
...