Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用bouncy castle在Java中创建SHA512摘要字符串?_Java_Hash_Bouncycastle_Sha512 - Fatal编程技术网

如何使用bouncy castle在Java中创建SHA512摘要字符串?

如何使用bouncy castle在Java中创建SHA512摘要字符串?,java,hash,bouncycastle,sha512,Java,Hash,Bouncycastle,Sha512,此单元测试失败: public void testDigest() throws NoSuchAlgorithmException { String hashExpected = "150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197"; MessageDigest md

此单元测试失败:

    public void testDigest() throws NoSuchAlgorithmException {
    String hashExpected = "150a14ed5bea6cc731cf86c41566ac427a8db48ef1b9fd626664b3bfbb99071fa4c922f33dde38719b8c8354e2b7ab9d77e0e67fc12843920a712e73d558e197";
    MessageDigest md = new MessageDigest();
    String hashActual = new String(md.digest("hi"));
    Assert.assertEquals(hashExpected, hashActual);
}
下面是我的MessageDigest类的实现:

}

测试失败的原因如下:
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));

junit.framework.ComparisonFailure:应为:但为:<
í[lÏ1φfÄBz�Žñýbfd³™É“ó=Þ8q›ŒƒT·«�wæÁ(C'
q、 sÕXá


当我将byte[]摘要转换为字符串时,我有一种感觉,我没有使用正确的编码方案。如果有任何帮助,我将不胜感激。

是的,您需要将字节数组转换为十六进制字符串。:-)查看,尤其是类。

您期望的值是十六进制编码的值。您正在基于原始字节创建一个字符串,这是行不通的

您应该尽可能使用标准Java Crypto API,而不是特定于BouncyCastle的API

尝试以下操作(十六进制库来自):


只是对Kevin答案的补充:自从Java5以来,您可以使用
String.format(“%0128x”,新的BigInteger(1,digesta))
代替commons编解码器,将字节数组格式化为带前导零的128位十六进制编码数字。

自BouncyCastle 1.49以来,
十六进制
类中有少量的
toHexString
方法。例如:

将以十六进制格式的Java
字符串
形式返回哈希摘要


参考请参见或。

+1我喜欢你更全面的答案。问题:何时/为什么要在数组上使用MessageDigest.isEqual?它们在功能上是等价的。MessageDigest#isEqual()提供了一点语义含义,但这是有争议的。它们都是等价的。数组方法认为两个空引用是相等的,而MasigeDigest.ISLIST方法将抛出一个Null PoExchange异常。公钥编解码器对于六进制转换是不必要的。尝试<代码> St.out。PrtLn(新BigType(1,M.文摘)。(新字节[]{0x00})).toString(16));关于MessageDigest#isEqual():它是时间常数,即计算所需的时间相同,并且在发现差异时不会立即返回false。这样,您就无法对函数调用计时以检查是否有一个哈希值,该哈希值具有与所需哈希值相同的前缀。谢谢您,但有一个问题。除了不需要拉入另一个库之外,还有其他库吗是否适合在commons编解码器答案中指定的方法上使用此方法?@jtbradle:可能不适合。

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