Получить совпадающие контрольные суммы между Java и C#

#java #c# #checksum #sha256

#java #c# #контрольная сумма #sha256

Вопрос:

Я переношу метод, который создает контрольную сумму для файла (в кодировке base64) из приложения C # на Java. В C # это метод:

 public static string GetChecksum(byte[] bytes)
{
    using (var stream = new MemoryStream(bytes))
    {
      var sha = new SHA256Managed();
      byte[] checksum = sha.ComputeHash(stream);
      return BitConverter.ToString(checksum).Replace("-", String.Empty);
    }
}
  

Вот что у меня есть в Java на данный момент, но это определенно не соответствует значению, возвращенному из C#:

 private static String getCheckSum(String base64Data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(base64Data.getBytes("UTF-8"));
        byte[] enc = md.digest();

        StringBuilder sb = new StringBuilder();
        for (byte b : enc) {
            sb.append(String.format("x", b));
        }

        return sb.toString().replace("-", "").toUpperCase();
    }
  

Я пробовал не использовать кодировку в getBytes() методе, я пробовал с кодировкой US-ASCII .

Этот материал не в моей компетенции, и я не уверен, как действовать дальше. Приветствуется любая помощь.

Комментарии:

1. string.getBytes вам не поможет. Он получит байтовые значения каждого отдельного символа в строке (используя выбранную кодировку символов, в вашем случае UTF-8). Он не будет декодировать строку Base64. Я не знаю о Java, но просмотрите документацию JDK для некоторого класса / метода, который выполняет декодирование base64…

2. @elgonzo . хорошо, давайте я попробую использовать декодер base64. Я сообщу об этом через несколько минут. Спасибо.

3. @elgonzo, … это сработало. Спасибо! Итак, сначала вы прокомментировали информацию, необходимую для решения проблемы, а вскоре это сделали несколько других людей. Немного неловко, что я сам этого не осознал, но… вы хотите, чтобы ваш комментарий был ответом, и я его приму?

4. Поскольку уже есть ответ относительно Base64-декодирования в Java, я чувствую, что мне не нужно добавлять еще один дублирующий ответ в микс 😉 Если один из ответов касается вашей проблемы и решает ее, не стесняйтесь принять его. Я не возражаю против того, чтобы не получать никаких очков репутации … 😉

5. @elgonzo, круто. Тем не менее, то, что вы начали действовать первым, навсегда останется в комментариях 🙂 Дайте им очки репутации.

Ответ №1:

В Java для декодирования строки Base64 у вас есть это (начиная с Java8) :

 byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);
  

от :https://www.baeldung.com/java-base64-encode-and-decode

Комментарии:

1. new String(decodedBytes) не подходит, когда декодированные байты действительно являются двоичными, а не текстовыми данными (и если это было бы уместно, было бы лучше явно указать набор символов).

Ответ №2:

Вы можете использовать библиотеку Guava для вычисления хэша.

 String sha256hex = Hashing.sha256()
  .hashString(originalString, StandardCharsets.UTF_8)
  .toString();
  

Кодек Apache commons также имеет библиотеку для вычисления хэша.

 String sha256hex = DigestUtils.sha256Hex(originalString);