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

huangapple go评论103阅读模式
英文:

Go SHA-256 hash differs from Java SHA-256 hash

问题

如果我在"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版本完全相同?

英文:

If I generate the SHA-256 hash in the language "GO", I get a different byte-Array compared to the Java equivalent.

This is the GO version:

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

The resulting array looks like:

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]

This one should do the same in Java code:

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

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

But results in this byte array

[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]

Why are they different? How do I need to change the java version to work exactly like the Go version?

答案1

得分: 16

为什么它们不同?

实际上它们并不不同,它们是相同的位。只是Java没有无符号字节 - 所以任何最高位设置的字节都是负数。在每种这样的情况下,你会看到Java的结果 = Go的结果 - 256。

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

英文:

> Why are they different?

They're not, really. They're the same bits. It's just that Java doesn't have unsigned bytes - so any byte with the top bit set is negative. In every case like that, you'll see that Java result = Go result - 256.

If you convert both byte arrays to hex or base64, you'll see same results.

答案2

得分: 4

以下是产生相同结果的Go代码:

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)
}

fmt文档中提到:

没有'u'标志。如果整数具有无符号类型,则打印为无符号。

由于数值类型定义了:

  • byteuint8的别名
  • 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=
英文:

Here is the Go code which would produce the same result:

<!-- language-all: go -->

package main

import &quot;fmt&quot;
import &quot;crypto/sha256&quot;

func main() {
	sum224 := sha256.Sum256([]byte(&quot;5nonce=5&quot;))
	s := make([]int8, sha256.Size)
	for i := range sum224 {
		s[i] = int8(sum224[i])
	}
	fmt.Printf(&quot;%d&quot;, 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]

The fmt doc does mention:

> There is no 'u' flag. Integers are printed unsigned if they have unsigned type.

Since Numeric Types defines:

  • byte alias for uint8
  • uint8 the set of all unsigned 8-bit integers (0 to 255)
  • int8 the set of all signed 8-bit integers (-128 to 127)

That is why you would need to convert byte (unsigned) into signed int8 to see the same.


If you add base64 encoding (see golang playground), you can get a result easier to compare:

import &quot;encoding/base64&quot;

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

That returns:

KU+668d7X+IQOzOhcPXAMhVCtPqzbZkS6ZQQ7ZxFo5Y=

huangapple
  • 本文由 发表于 2014年6月28日 06:27:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/24461629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定