我想使用 MessageDigest 类对 Java 中的两个 BigInteger 进行哈希处理。
到目前为止我有以下代码
// SHA(v concantenated with n)
public void calculateProversCertificate(BigInteger v, BigInteger n)
{
MessageDigest md;
try
{
md = MessageDigest.getInstance("SHA-1");
md.update(v.toByteArray());
md.update(n.toByteArray());
byte[] byteData = md.digest();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < byteData.length; i++)
{
sb.append(Integer.toString((byteData[i] & 0xFF) + 0x100, 16).substring(1));
}
String hash = sb.toString();
System.out.println("Certificate:" + hash);
}
catch (NoSuchAlgorithmException ex)
{
System.out.println("Could not create SHA MessageDigest class");
}
}
我的代码可以计算哈希值,但当打印为字符串时,它的长度不正确。我使用此代码从用户密码创建“cookie”,我想对其进行调整以查找两个 BigIntegers 的哈希值。我特别不确定 for 循环及其工作原理。我假设它将 Byte[] 重新加入到可以表示为字符串的内容中。尽管对于它是如何做到这一点有点超出我的理解。
有人可以解释一下循环背后的想法,以及它是如何构建字符串的吗?另外我如何调整它以产生如下例所示的输出?
基本上我正在寻找类似这样的输出
1tdgsp8bs0gk72dbvpu0be33tv2dobimc4mg07d209401mrhbe23qe1tdh7jcd78so46ffet20lqemlakv4mfvbk6fjp9a2th9bhb2
但是我得到了类似的东西(由代码中的 print 语句生成)
9aa1770b83257b2c7b2a6fb9684253930781c0cf
示例 V 和 N(由 BigInteger.toString() 生成;)
V: 1678202601632665039275603893340186995409970283833828187403506666684692322312620073622777464636561237395218125410336245265888297965169878433803688272535099
N: 8449118772240198089422438092628650298318511756191052993769148184590886001852753186246607550316706472668220614311553576373631078947139889888957411418229019
最佳答案
该循环看起来是将字节数组转换为十六进制字符串的复杂方法。它获取每个字节值,应用一个可怕的函数将其转换为两个十六进制字符,并将它们附加到 StringBuilder
中。
我不知道为什么作者不直接在循环内使用Integer.toHexString
,或者更好的是String.format
。其中任何一个都会比您现在所拥有的容易得多。
请注意,byteData[i] & 0xFF
不执行任何操作(除了提升为 int
之外,您不需要这样做,因为字节值可以自动提升为 int)。 byteData[i]
是一个字节
,对字节值执行& 0xFF
是无操作。
无论如何,这段代码似乎生成了正确的输出。 SHA-1 生成 160 位哈希值,看起来像 40 个字符的十六进制字符串。十六进制对每个字符 4 位进行编码,因此这似乎是哈希值的有效编码(40 个字符 * 每个字符 4 位 = 哈希中的 160 位)
Basically I am looking for output something like this 1tdgsp8bs0gk72dbvpu0be33tv2dobimc4mg07d209401mrhbe23qe1tdh7jcd78so46ffet20lqemlakv4mfvbk6fjp9a2th9bhb2
你从哪里得到这个字符串?为什么你期望你的哈希输出看起来像这样?
顺便说一句,我希望您没有真正实现自己的证书检查。众所周知,加密代码很难正确使用,因此您应该使用现有的库。如果您推出自己的加密货币,您将有一个漏洞(可能有很多漏洞)。
关于java - 查找两个大整数的 SHA-1 哈希值并将其作为字符串返回的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22214513/