0

Вычисление SHA-1 для массива байтов

10

Я ищу способ получить SHA-1 контрольную сумму для массива байтов в Java.

Должен ли я использовать сторонний инструмент или есть встроенные средства в JVM, которые могут помочь в этом?

5 ответ(ов)

0

Ваш код на Java вычисляет SHA-1 хэш для входного массива байтов и возвращает его в шестнадцатеричном формате. Вот краткое объяснение и некоторые замечания:

  1. Импорт библиотек: Вы импортируете необходимые классы MessageDigest, NoSuchAlgorithmException и Formatter. Это позволяет выполнять криптографические операции и форматирование строк.

  2. Метод SHAsum:

    • Этот метод принимает массив байтов в качестве параметра.
    • Сначала он создает экземпляр MessageDigest с использованием алгоритма SHA-1.
    • Затем он вычисляет хэш, вызывая метод digest и передает в него массив байтов.
    • После этого результат передается в метод byteArray2Hex, который преобразует массив байтов в строку шестнадцатеричного формата.
  3. Метод byteArray2Hex:

    • Этот метод принимает массив байтов и используется для форматирования каждого байта в соответствующую шестнадцатеричную строку.
    • Используя Formatter, вы проходите по каждому байту, применяя форматирование с ведущим нулем (%02x), что гарантирует, что каждый байт будет представлен в виде двух шестнадцатеричных символов.
  4. Обработка исключений: Обратите внимание, что метод SHAsum объявляет, что он может выбросить NoSuchAlgorithmException. Это исключение может возникнуть, если указанный алгоритм не поддерживается.

Замечания:

  • Обратите внимание, что SHA-1 считается устаревшим и не рекомендуется для новых проектов из-за известных слабостей. Если вам нужен более безопасный хэш, подумайте о использовании SHA-256 или более современного алгоритма.
  • Рассмотрите использование try-with-resources для Formatter, чтобы обеспечить его закрытие после использования.

Пример улучшенного кода с использованием SHA-256 может выглядеть так:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;

public static String SHAsum(byte[] convertme) throws NoSuchAlgorithmException{
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    return byteArray2Hex(md.digest(convertme));
}

private static String byteArray2Hex(final byte[] hash) {
    try (Formatter formatter = new Formatter()) {
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        return formatter.toString();
    }
}

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

0

Для реализации хэширования с SHA-1 и преобразования результата в шестнадцатеричную строку, можно использовать следующую функцию. Метод DigestUtils из библиотеки Apache Commons Codec предоставляет средства для подобной операции. Рассмотрим код, который вы упомянули, и его адаптацию.

Сначала вам нужно импортировать необходимые классы:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.DecoderException;

Теперь, вот как вы можете реализовать функцию с использованием описанной вами логики:

public static String exampleSha1(String convertme) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] digest = md.digest(convertme.getBytes());
    return byteArrayToHex(digest);
}

private static String byteArrayToHex(byte[] data) {
    final char[] DIGITS = "0123456789abcdef".toCharArray(); // Используем строчные буквы для шестнадцатеричного представления
    StringBuilder hexString = new StringBuilder(data.length * 2);
    for (byte b : data) {
        hexString.append(DIGITS[(b >> 4) & 0x0F]);
        hexString.append(DIGITS[b & 0x0F]);
    }
    return hexString.toString();
}

В этой реализации:

  1. MessageDigest используется для вычисления хэш-суммы строки convertme.
  2. Результат хэширования (массив байтов) передается в метод byteArrayToHex, который преобразует массив байтов в строку в шестнадцатеричном формате.
  3. В byteArrayToHex мы проходим по каждому байту и добавляем его шестнадцатеричное представление в результирующую строку.

Этот метод обеспечит корректное преобразование данных в нужный формат, используя встроенные возможности Java и, при необходимости, дополнительные функции библиотеки Commons Codec.

0

Вам нужно проверить контрольную сумму SHA-1 внутри файла DEX и сравнить её с уже сохранённым значением? Вот пример кода на Java, который делает это. Учтите, что стиль кода может быть не идеальным, так как он предназначен больше для демонстрации (Proof of Concept), чем для использования в продакшен-коде. Надеюсь, это поможет вам в вашем исследовании!

class CheckDex {
    public boolean checkSHA1(File f) throws IOException, NoSuchAlgorithmException {
        RandomAccessFile raf = new RandomAccessFile(f, "r");
        byte[] sig = new byte[20];
        raf.seek(0xC); // Переходим к позиции, где хранится контрольная сумма
        for (int i = 0; i < 20; i++) {
            sig[i] = (byte) raf.readUnsignedByte(); // Считываем контрольную сумму
        }

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

        byte[] code = new byte[(int) (raf.length() - 32)]; // Загружаем код, исключая последние 32 байта
        for (int i = 0; i < code.length; i++) {
            code[i] = (byte) raf.readUnsignedByte(); // Читаем код
        }
        byte[] comsig = md.digest(code); // Вычисляем контрольную сумму

        raf.close();
        return Arrays.equals(sig, comsig); // Сравниваем контрольные суммы
    }
}

Описание работы кода:

  1. Считывание контрольной суммы: Метод checkSHA1 открывает файл DEX и считывает контрольную сумму SHA-1, находящуюся на позиции 0xC.
  2. Вычисление контрольной суммы: Далее, код считывается в массив и вычисляется его контрольная сумма с помощью MessageDigest.
  3. Сравнение контрольных сумм: В конце метода контрольная сумма из файла сравнивается с рассчитанной.

Пожалуйста, дайте знать, если у вас есть дополнительные вопросы!

0

Конечно! Если вам нужно вычислить SHA-1 хэш для файла в Java, вот пример кода, который делает это:

public class Sha1Calculate {

    public static void main(String[] args) throws Exception {
        File file = new File("D:\\Android Links.txt");
        String outputTxt = "";
        String hashcode = null;

        try {
            FileInputStream input = new FileInputStream(file);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[65536];
            int l;

            // Чтение файла в буфер
            while ((l = input.read(buffer)) > 0) {
                output.write(buffer, 0, l);
            }

            input.close();
            output.close();

            byte[] data = output.toByteArray();

            // Создание экземпляра MessageDigest для SHA-1
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(data);
            byte[] bytes = digest.digest();

            // Преобразование байтового массива в шестнадцатеричный формат
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                sb.append(String.format("%02X", b));
            }

            System.out.println("Digest (в шестнадцатеричном формате): " + sb.toString());

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}

Объяснение кода:

  1. Импортируем нужные классы: Для работы с файлами и вычисления хешей.
  2. Создаем объект File, указывая путь к файлу, SHA-1 которого мы хотим вычислить.
  3. Читаем файл в байтовый массив с использованием FileInputStream и ByteArrayOutputStream.
  4. Создаем экземпляр MessageDigest и вычисляем SHA-1 хеш.
  5. Преобразуем байты в шестнадцатеричное представление и выводим результат.

Этот код обрабатывает исключения, такие как FileNotFoundException, IOException и NoSuchAlgorithmException для гарантии надежности выполнения. Не забудьте, что для корректного выполнения кода необходимо, чтобы файл существовал по указанному пути.

0

Этот код преобразует данный byte[] в строку, представляющую SHA-1 хеш.

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public static String hash(byte data[]) throws NoSuchAlgorithmException
{
   MessageDigest digest;
   BigInteger big;
   String result;
   byte hash[];

   digest = MessageDigest.getInstance("SHA-1"); 
   hash   = digest.digest(data);
   big    = new BigInteger(1, hash);
   result = big.toString(16);

   return result;
}

Обратите внимание: начальные нули будут отброшены. Поэтому в зависимости от вашего случая использования этот метод может не подойти. Если вам нужно сохранить ведущие нули, вы можете изменить код, чтобы отформатировать строку с использованием String.format, например:

result = String.format("%040x", big);

Эта модификация гарантирует, что строка всегда будет иметь длину 40 символов, добавляя ведущие нули, где это необходимо.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь