Come posso creare una stringa digest SHA512 in Java utilizzando castello gonfiabile?
-
18-09-2019 - |
Domanda
Questo test unità sta venendo a mancare:
public void testDigest() throws NoSuchAlgorithmException {
String hashExpected = "150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197";
MessageDigest md = new MessageDigest();
String hashActual = new String(md.digest("hi"));
Assert.assertEquals(hashExpected, hashActual);
}
Di seguito è la mia realizzazione della mia 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;
}
}
Il test ha esito negativo con la seguente motivazione:
junit.framework.ComparisonFailure: expected:<150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197> but was:<
í[êlÇ1φÄf¬Bz�´Žñ¹ýbfd³¿»™¤É"ó=Þ8q›ŒƒTâ·«�wàæÁ(C’
q.sÕXá
Ho la sensazione che non sto usando lo schema di codifica a destra quando si converte il mio byte [] digerire in una stringa. Qualsiasi aiuto sarebbe apprezzato.
Soluzione
Il valore ci si aspetta è un valore esadecimale con codifica. Si sta creando una stringa in base ai byte prime, che non funzioneranno.
Si dovrebbe utilizzare l'API standard di Java Crypto, quando possibile, invece di API specifiche BouncyCastle.
Provare la seguente (la libreria Hex viene da ):
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));
Altri suggerimenti
Proprio un'aggiunta alla risposta di Kevin:. Dal momento che Java 5, è possibile utilizzare String.format("%0128x", new BigInteger(1, digesta))
invece di commons-codec per formattare l'array di byte come un numero codificato a 128 cifre esadecimale con zeri
Sì, è necessario trasformare il vostro array di byte in una stringa esadecimale. :-) Se vuoi in Apache Commons Codec , in particolare il Hex classe.
Dal BouncyCastle 1.49 v'è un metodo toHexString
manciata nella classe Hex
. Ad esempio:
Hex.toHexString(digest);
restituirà la hash digest come String
Java in un formato esadecimale.
Per riferimento vedere BouncyCastle javadoc o grepcode .