Как я могу создать строку дайджеста SHA512 в Java, используя bouncy castle?

StackOverflow https://stackoverflow.com/questions/2208374

Вопрос

Этот модульный тест завершается неудачей:

    public void testDigest() throws NoSuchAlgorithmException {
    String hashExpected = "150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197";
    MessageDigest md = new MessageDigest();
    String hashActual = new String(md.digest("hi"));
    Assert.assertEquals(hashExpected, hashActual);
}

Ниже приведена моя реализация моего класса MessageDigest:


import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

импортировать org.bouncycastle.crypto.Дайджест;импортировать org.bouncycastle.crypto.дайджесты.SHA512Digest;импортировать org.bouncycastle.crypto.io.DigestInputStream;импортировать org.bouncycastle.jce.provider.BouncyCastleProvider;

открытый класс MessageDigest { частный дайджест MessageDigest;

public MessageDigest() throws NoSuchAlgorithmException {
    Security.addProvider(new BouncyCastleProvider());
    messageDigest = new SHA512Digest();
}

public byte[] digest(String message) {
    byte[] retValue = new byte[messageDigest.getDigestSize()];
    messageDigest.update(message.getBytes(), 0, message.length());
    messageDigest.doFinal(retValue, 0);
    return retValue;
}

}

Тест завершается неудачей по следующей причине:


junit.framework.ComparisonFailure: expected:<150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197> but was:<
í[êlÇ1φÄf¬Bz�´Žñ¹ýbfd³¿»™¤É"ó=Þ8q›ŒƒTâ·«�wàæÁ(C’
q.sÕXá

У меня такое чувство, что я не использую правильную схему кодирования, когда преобразую свой дайджест byte[] в строку.Будем признательны за любую помощь.

Это было полезно?

Решение

Ожидаемое вами значение имеет шестнадцатеричную кодировку.Вы создаете Строку на основе необработанных байтов, которая не будет работать.

Вы должны использовать стандартный Java Crypto API, когда это возможно, вместо специфичных для BouncyCastle API.

Попробуйте следующее (библиотека Hex поступает из commons-кодек):

Security.addProvider(new BouncyCastleProvider());

String data = "hello world";

MessageDigest mda = MessageDigest.getInstance("SHA-512", "BC");
byte [] digesta = mda.digest(data.getBytes());

MessageDigest mdb = MessageDigest.getInstance("SHA-512", "BC");
byte [] digestb = mdb.digest(data.getBytes());

System.out.println(MessageDigest.isEqual(digesta, digestb));

System.out.println(Hex.encodeHex(digesta));

Другие советы

Просто дополнение к ответу Кевина:Начиная с Java 5, вы можете использовать String.format("%0128x", new BigInteger(1, digesta)) вместо commons-кодек для форматирования массива байтов в виде 128-значного шестнадцатеричного числа с начальными нулями.

Да, вам нужно превратить ваш массив байтов в шестнадцатеричную строку.:-) Загляните в Кодек Apache Commons для общего доступа, особенно в Шестнадцатеричный класс.

Начиная с BouncyCastle 1.49, существует несколько toHexString метод в Hex класс.Например:

Hex.toHexString(digest);

вернет вам хэш-дайджест в виде Java String в шестнадцатеричном формате.

Для справки смотрите Надувной замок джавадок или grepcode ( код grepcode ).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top