java - 查找两个大整数的 SHA-1 哈希值并将其作为字符串返回的正确方法

标签 java math hash

我想使用 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/

相关文章:

arrays - 如何有效地将变量转换为模式中的数组

python - 如何在 matplotlib 中找到函数下方的区域?

c - 在没有条件语句的情况下找到更大的数字

java - Java 中的 equals 方法不起作用

java - 如何在异步连接返回时切换 Activity ?

java - 我可以在方法体内使用注解吗?

java - 从 Android 2017 中的 URL 中提取 JSON 数据

c# - ruby 中的 hmac-sha1 不同于 C# HMACSHA1

python - 在 python 中对集合进行散列冲突的成员资格测试

C# 为字节数组或图像创建哈希