无法在Java中输出正确的哈希值。怎么了? [英] Cannot output correct hash in Java. What is wrong?

查看:173
本文介绍了无法在Java中输出正确的哈希值。怎么了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Android应用程序中,我有一个SHA256哈希,我必须使用RIPEMD160消息摘要算法进一步哈希。

In my Android app I have a SHA256 hash which I must further hash with the RIPEMD160 message digest algorithm.

我可以输出任何正确的sha256和ripemd160哈希值字符串,但是当我尝试使用ripemd160散列sha256哈希时,我得到一个不正确的哈希。

I can output the correct sha256 and ripemd160 hash of any string, but when I try to hash the sha256 hash with ripemd160 I get a hash which is incorrect.

根据在线哈希计算器,字符串'test的SHA256值'(全部小写)是:

According to online hash calculators, the SHA256 value of the string 'test'(all lowercase) is:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

字符串'test'的RIPEMD160值为:

And the RIPEMD160 value of the string 'test' is:

5e52fee47e6b070565f74372468cdc699de89107

根据在线计算,使用ripemd160散列生成的sha256哈希的值是:

The value from hashing the resulting sha256 hash with ripemd160 according to online calcs is:

4efc1c36d3349189fb3486d2914f56e05d3e66f8

一个我的应用程序给我的是:

And the one my app gives me is:

cebaa98c19807134434d107b0d3e5692a516ea66

这显然是错误的。

这是我的代码:

public static String toRIPEMD160(String in)
{
    byte[] addr = in.getBytes();
    byte[] out = new byte[20];
    RIPEMD160Digest digest = new RIPEMD160Digest();
    byte[] sha256 = sha256(addr);
    digest.update(sha256,0,sha256.length);
    digest.doFinal(out,0);
    return getHexString(out);
}

public static byte[] sha256(byte[] data)
{
    byte[] sha256 = new byte[32];
    try
    {
        sha256 = MessageDigest.getInstance("SHA-256").digest(data);
    }
    catch(NoSuchAlgorithmException e)
    {}

    return sha256;
}

对于ripemd160算法,sha256需要bouncycastle和java.security.MessageDigest 。

For the ripemd160 algorithm, you need bouncycastle and java.security.MessageDigest for sha256.

推荐答案

你的哈希工作正常。问题是你正在使用的在线计算器正在处理你的输入:

Your hash is working fine. The problem is that the online calculators that you're using are treating your input:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

作为字符串而不是字节数组。换句话说,它将每个字符视为一个字节,而不是将字符对解析为十六进制的字节。如果我把它作为一个字符串给在线计算器,我确实得到你所得到的:

as a string instead of an array of bytes. In other words, it's treating each character as a byte instead of parsing character pairs as bytes in hexadecimal. If I give this as a string to online calculators, I indeed get exactly what you got:

4efc1c36d3349189fb3486d2914f56e05d3e66f8

但是,您将输出视为字节数组而不是字符串,这会给你不同的结果。您应该将原始SHA256哈希编码为字符串,然后将编码的字符串传递给哈希函数。我看到你有一个 getHexString 方法,所以我们只是使用它。

However, you're treating the output as an array of bytes instead of a String and that's giving you different results. You should encode your raw SHA256 hash as a string, then pass the encoded string to the hash function. I see you have a getHexString method, so we'll just use that.

public static String toRIPEMD160(String in) {
    try {
        byte[] addr = in.getBytes();
        byte[] out = new byte[20];
        RIPEMD160Digest digest = new RIPEMD160Digest();

        // These are the lines that changed
        byte[] rawSha256 = sha256(addr);
        String encodedSha256 = getHexString(rawSha256);
        byte[] strBytes = encodedSha256.getBytes("UTF-8");
        digest.update(strBytes, 0, strBytes.length);

        digest.doFinal(out, 0);
        return getHexString(out);
    } catch (UnsupportedEncodingException ex) {
        // Never happens, everything supports UTF-8
        return null;
    }
}

如果你想知道它的工作原理,请选择价值 encodedSha256 并将其放入在线哈希计算器中。只要计算器使用UTF-8编码将字符串转换为字节数组,它就会匹配您的输出。

If you want to know it's working, take the value of encodedSha256 and put that into an online hash calculator. As long as the calculator uses UTF-8 encoding to turn the string into a byte array, it will match your output.

这篇关于无法在Java中输出正确的哈希值。怎么了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆