Go SHA-256哈希与Java SHA-256哈希不同

时间:2014-06-27 22:27:06

标签: java hash go sha

如果我使用语言" GO"生成SHA-256哈希,与Java等效语句相比,我获得了不同的字节数组。

这是GO版本:

fmt.Println(getSha256([]byte("5nonce=5")))

结果数组如下所示:

41 79 186 235 199 123 95 226 16 59 51 161 112 245 192 50 21 66 180 250 179 109 153 18 233 148 16 237 156 69 163 150]

这个应该在Java代码中做同样的事情:

MessageDigest md = MessageDigest.getInstance("SHA-256");

md.update("5nonce=5".getBytes()); 
byte[] digest = md.digest();

但结果是这个字节数组

[41, 79, -70, -21, -57, 123, 95, -30, 16, 59, 51, -95, 112, -11, -64, 50, 21, 66, -76, -6, -77, 109, -103, 18, -23, -108, 16, -19, -100, 69, -93, -106]

为什么他们不一样?如何更改java版本才能像Go版本一样工作?

2 个答案:

答案 0 :(得分:17)

  

为什么他们不同?

他们不是,真的。它们是相同的位。只是Java没有无符号字节 - 因此任何顶部位设置的字节都是负数。在每种情况下,你都会看到Java结果= Go结果 - 256。

如果将两个字节数组转换为十六进制或base64,您将看到相同的结果。

答案 1 :(得分:4)

Here is the Go code会产生相同的结果:

package main

import "fmt"
import "crypto/sha256"

func main() {
    sum224 := sha256.Sum256([]byte("5nonce=5"))
    s := make([]int8, sha256.Size)
    for i := range sum224 {
        s[i] = int8(sum224[i])
    }
    fmt.Printf("%d", s)
}

[41 79 -70 -21 -57 123 95 -30 16 59 51 -95 112 -11 -64 50 21 66 -76 -6 -77 109 -103 18 -23 -108 16 -19 -100 69 -93 -106]

fmt doc确实提到了:

  

没有' u'旗。如果整数具有无符号类型,则它们将无符号打印。

由于Numeric Types定义:

  • byte
  • uint8别名
  • uint8所有无符号8位整数(0到255)的集合
  • int8所有带符号的8位整数集(-128到127)

这就是为什么您需要将byte(无符号)转换为签名int8才能看到相同内容。


如果您添加base64编码(请参阅golang playground),您可以更轻松地比较结果:

import "encoding/base64"

res := base64.StdEncoding.EncodeToString([]byte(sum224[:]))
fmt.Println(res)

返回:

KU+668d7X+IQOzOhcPXAMhVCtPqzbZkS6ZQQ7ZxFo5Y=