Como posso criar uma cadeia de SHA512 digest em Java usando castelo insuflável?
-
18-09-2019 - |
Pergunta
Este teste de unidade está a falhar:
public void testDigest() throws NoSuchAlgorithmException {
String hashExpected = "150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197";
MessageDigest md = new MessageDigest();
String hashActual = new String(md.digest("hi"));
Assert.assertEquals(hashExpected, hashActual);
}
Abaixo está a minha aplicação da minha classe MessageDigest:
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.io.DigestInputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class MessageDigest {
private Digest 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;
}
}
O teste falha com o seguinte motivo:
junit.framework.ComparisonFailure: expected:<150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197> but was:<
í[êlÇ1φÄf¬Bz�´Žñ¹ýbfd³¿»™¤É"ó=Þ8q›ŒƒTâ·«�wàæÁ(C’
q.sÕXá
Eu tenho um sentimento que eu não estou usando o esquema de codificação certo quando eu converter meu byte [] digerir em uma string. Qualquer ajuda seria apreciada.
Solução
O valor que você está esperando é um valor Hex-codificado. Você está criando uma cadeia com base nos bytes brutos, que não vai funcionar.
Você deve usar o padrão API Java Crypto, sempre que possível, em vez de APIs específicas BouncyCastle.
Tente o seguinte (a biblioteca Hex vem commons-codec ):
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));
Outras dicas
Apenas uma adição à resposta de Kevin:. Desde Java 5, você pode usar String.format("%0128x", new BigInteger(1, digesta))
vez de commons-codec para formatar a matriz de bytes como um número codificado de 128 dígitos hex com zeros à esquerda
Sim, você precisa para transformar sua matriz de bytes em uma string hexadecimal. :-) Olhe em Apache Commons Codec , especialmente o Hex classe.
Desde BouncyCastle 1,49 existe um método toHexString
punhado na classe Hex
. Por exemplo:
Hex.toHexString(digest);
irá retornar o hash digerir como um String
Java em um formato hexadecimal.
Para referência ver BouncyCastle javadoc ou grepcode .