在我的Android应用程序中,我有一个SHA256哈希,我必须使用RIPEMD160消息摘要算法进一步哈希。
我可以输出任何字符串的正确sha256和ripemd160哈希,但是当我尝试使用ripemd160散列sha256哈希时,我得到的哈希值不正确。
根据在线哈希计算器,字符串'test'(全部小写)的SHA256值为:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
字符串'test'的RIPEMD160值为:
5e52fee47e6b070565f74372468cdc699de89107
根据在线计算,使用ripemd160散列生成的sha256哈希的值是:
4efc1c36d3349189fb3486d2914f56e05d3e66f8
我的应用程序给我的是:
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。
答案 0 :(得分:7)
您的“在线计算器”结果是使用SHA-256对字符串“test”的字节进行哈希处理,将该哈希值的结果转换为十六进制字符串,然后获取与该十六进制的ASCII字符对应的字节的结果字符串和第二次哈希。这与您的Java代码非常不同,Java代码将第一个散列中的字节直接传递给第二个散列,而不将它们打印为十六进制并将这些字符转换回其间的字节。值为254(十进制)的单字节在十六进制中变为“fe”,在转换回字节时变为双字节序列[0x66,0x65]。
答案 1 :(得分:3)
你的哈希工作正常。问题是你正在使用的在线计算器正在处理你的输入:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
作为字符串而不是字节数组。换句话说,它将每个字符视为一个字节,而不是将字符对解析为十六进制的字节。如果我把它作为一个字符串给在线计算器,我确实得到你所得到的:
4efc1c36d3349189fb3486d2914f56e05d3e66f8
但是,您将输出视为一个字节数组而不是String
,这会给您不同的结果。您应该将原始SHA256哈希编码为字符串,然后将编码的字符串传递给哈希函数。我看到你有一个getHexString
方法,所以我们只是使用它。
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编码将字符串转换为字节数组,它就会匹配您的输出。
答案 2 :(得分:1)
要获取byte[]
摘要的可打印版本,请使用以下代码:
StringBuffer hexString = new StringBuffer();
for (int i=0;i<out.length;i++) {
hexString.append( String.format("%02x", 0xFF & out[i]) );
}
然后拨打hexString.toString();