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

发布于 2024-08-20 08:52:40 字数 1639 浏览 5 评论 0原文

该单元测试失败:

    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.Digest; 导入 org.bouncycastle.crypto.digests.SHA512Digest; 导入 org.bouncycastle.crypto.io.DigestInputStream; 导入 org.bouncycastle.jce.provider.BouncyCastleProvider;

公共类消息摘要{ 私人摘要消息摘要;

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[] 摘要转换为字符串时,我有一种感觉没有使用正确的编码方案。任何帮助将不胜感激。

This unit test is failing:

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

Below is my implementation of my MessageDigest class:


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;
}

}

The test fails with the following reason:


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

I have a feeling I'm not using the right encoding scheme when I convert my byte[] digest into a string. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

猫九 2024-08-27 08:52:40

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

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

尝试以下操作(十六进制库来自 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));

The value you're expecting is a Hex-encoded value. You're creating a String based on the raw bytes, which won't work.

You should use the standard Java Crypto API whenever possible instead of BouncyCastle specific APIs.

Try the following (the Hex library comes from 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));
蓝眸 2024-08-27 08:52:40

只是对 Kevin 的回答的补充:从 Java 5 开始,您可以使用 String.format("%0128x", new BigInteger(1,digesta)) 而不是 commons-codec 将字节数组格式化为带前导零的 128 位十六进制编码数字。

Just an addition to Kevin's answer: Since Java 5, you can use String.format("%0128x", new BigInteger(1, digesta)) instead of commons-codec to format the byte array as a 128 digit hex encoded number with leading zeros.

痴意少年 2024-08-27 08:52:40

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

Yes, you need to turn your byte array into a hex string. :-) Look into Apache Commons Codec, especially the Hex class.

吃→可爱长大的 2024-08-27 08:52:40

从 BouncyCastle 1.49 开始,Hex 类中有一些 toHexString 方法。例如:

Hex.toHexString(digest);

将以十六进制格式的 Java String 形式返回哈希摘要。

有关参考,请参阅 BouncyCastle javadocgrepcode

Since BouncyCastle 1.49 there is a handful toHexString method in the Hex class. For example:

Hex.toHexString(digest);

will return you the hash digest as a Java String in a hexadecimal format.

For reference see BouncyCastle javadoc or grepcode.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文