go 中的 sha1 与 python 和 openssl 中的不同

sha1 different in go than in python and openssl

我正在尝试在 go 中构建一个 base64 编码的 sha1 哈希,但我得到的结果与其他编程语言的结果非常不同

package main

import (
    "crypto/sha1"
    "encoding/base64"
    "fmt"
)

func main() {
    c := sha1.New()
  input := []byte("hello")
  myBytes := c.Sum(input)
  fmt.Println(base64.StdEncoding.EncodeToString(base64.StdPadding))
}

这段 Go 代码打印出 aGVsbG/aOaPuXmtLDTJVv++VYBiQr9gHCQ==

我的 Python 代码如下所示

import hashlib
import base64


print(base64.b64encode(hashlib.sha1('hello').digest()))

并输出qvTGHdzF6KLavt4PO0gs2a6pQ00=

我的 bash 比较命令如下所示

echo -n hello| openssl dgst -sha1 -binary |base64

并输出这个qvTGHdzF6KLavt4PO0gs2a6pQ00=

这让我假设 python 代码一切正常。 但是为什么去打印另一个结果。 我的错误在哪里?

提前致谢

您使用标准库的方式完全错误。不要假设方法/函数的作用,如果它对您来说是新的,请务必阅读文档。

sha1.New() returns a hash.Hash。它的Sum()方法是不是计算哈希值,而是得到当前的哈希结果,不改变底层哈希状态

hash.Hash实现了io.Writer,为了计算一些数据的散列,你必须把那个数据写入其中。 Hash.Sum() 如果您已经分配了一个可选切片,则将结果(哈希)写入其中。如果你想让它分配一个新的,就传nil

另外base64.StdEncoding.EncodeToString()需要你要转换成base64的字节数据(byte slice),所以你必须把checksum数据传给它。在您的代码中,您没有告诉 EncodeToString() 要编码什么。

工作示例:

c := sha1.New()
input := []byte("hello")
c.Write(input)
sum := c.Sum(nil)
fmt.Println(base64.StdEncoding.EncodeToString(sum))

输出符合预期(在 Go Playground 上尝试):

qvTGHdzF6KLavt4PO0gs2a6pQ00=

请注意,crypto/sha1 package also has a handy sha1.Sum() 函数一步完成:

input := []byte("hello")
sum := sha1.Sum(input)
fmt.Println(base64.StdEncoding.EncodeToString(sum[:]))

输出相同。在 Go Playground.

上试试

有一个 example 如何正确使用它。你应该这样做:

c := sha1.New()
io.WriteString(c, "hello")
myBytes := c.Sum(nil)
fmt.Println(base64.StdEncoding.EncodeToString(myBytes))

https://play.golang.org/p/sELsWTcrdd