Хеш-функция SHA дает отрицательный вывод - PullRequest
4 голосов
/ 15 июня 2011

Я пытаюсь реализовать алгоритм подписи DSA, и я застрял в проблеме.Я использую класс java.security MessageDigest, вот код:

MessageDigest md;
md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes());
return new BigInteger(md.digest());

Текст - это случайный объект String.Проблема в том, что этот код дает мне отрицательные значения хэша, которые не принимаются алгоритмом.Я делаю что-то неправильно?Заранее спасибо.

PS Кстати, я также пытался реализовать DSA без использования BigIntegers, возможно ли это?Я не нашел значения L и N меньше, чем 1024 и 160, поэтому я понятия не имею, какие значения я должен принимать и какую хеш-функцию я должен использовать.Буду очень благодарен за ответы на эти вопросы.

Ответы [ 4 ]

3 голосов
/ 15 июня 2011
MessageDigest md;
md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes());
return new BigInteger(1, md.digest()); // use this 1 to tell it is positive.

Затем вы можете преобразовать свой хэш в строку, используя:

String hash = biginteger.toString(16);

Затем, при необходимости, добавьте начальные нули.

String zeros = String.format("%032d", 0);
hash = zeros.substring(hash.length()) + hash;
2 голосов
/ 15 июня 2011

Почему ты удивлен?MessageDigest#digest() возвращает равномерно распределенные 160 бит данных.Обычно они представляются в виде шестнадцатеричной строки, но если вы преобразуете их в целое число, самый значимый бит обозначает знак.Проверьте этот код:

System.out.println(new BigInteger(new byte[]{(byte) 255}));  //-1
1 голос
/ 15 июня 2011

Вы передаете байты, возвращенные конструктору BigInteger .Хотя типы совпадают, я не уверен, чего вы хотите достичь здесь.Из BigInteger JavaDoc:

Переводит байтовый массив, содержащий двоичное представление с двумя дополнениями BigInteger

0 голосов
/ 15 июня 2011

Не изобретайте колесо, особенно для криптографии - используйте java.security.Signature или библиотеку более высокого уровня.

...