在Go、Python和OpenSSL中,SHA1算法的结果可能会有所不同。

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

sha1 different in go than in python and openssl

问题

我正在尝试在Go语言中构建一个Base64编码的SHA1哈希,但是我得到的结果与其他编程语言的结果非常不同。

这是我的Go代码:

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代码是正确的。但为什么Go语言输出了另一个结果呢?我犯了什么错误?

提前感谢您的帮助!

英文:

I am trying to build a base64 encoded sha1 hash in go but the result i am getting is very different to the results of other programming languages

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

This Go Code prints out aGVsbG/aOaPuXmtLDTJVv++VYBiQr9gHCQ==

My Python Code Looks like this

import hashlib
import base64


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

And outputs qvTGHdzF6KLavt4PO0gs2a6pQ00=

My bash command for comparison looks like this

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

And outputs this qvTGHdzF6KLavt4PO0gs2a6pQ00=

Which lets me assume that the python code is doing everything correct.
But why does go prints another result.
Where is my mistake?

Thnx in advance

答案1

得分: 10

你完全错误地使用了标准库。不要假设一个方法/函数的作用,如果对它不熟悉,总是要阅读文档。

sha1.New() 返回一个 hash.Hash 对象。它的 Sum() 方法不是用来计算哈希值的,而是用来获取当前的哈希结果,它不会改变底层的哈希状态。

hash.Hash 实现了 io.Writer 接口,要计算某些数据的哈希值,你需要将数据写入其中。如果你已经分配了一个切片,Hash.Sum() 可以接受一个可选的切片参数,用来将结果(哈希值)写入其中。如果你想要它分配一个新的切片,可以传入 nil

另外,base64.StdEncoding.EncodeToString() 期望的是你要转换为 base64 的字节数据(字节切片),所以你需要将校验和数据传递给它。在你的代码中,你没有告诉 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 包还提供了一个方便的 sha1.Sum() 函数,可以一步完成这个操作:

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

输出结果相同。可以在 Go Playground 上尝试。

英文:

You use the standard lib in a completely wrong way. Don't assume what a method / function does, always read the docs if it's new to you.

sha1.New() returns a hash.Hash. Its Sum() method is not to calculate the hash value, but to get the current hash result, it does not change the underlying hash state.

hash.Hash implements io.Writer, and to calculate the hash of some data, you have to write that data into it. Hash.Sum() takes an optional slice if you already have one allocated, to write the result (the hash) to it. Pass nil if you want it to allocate a new one.

Also base64.StdEncoding.EncodeToString() expects the byte data (byte slice) you want to convert to base64, so you have to pass the checksum data to it. In your code you didn't tell EncodeToString() what to encode.

Working example:

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

Output is as expected (try it on the Go Playground):

qvTGHdzF6KLavt4PO0gs2a6pQ00=

Note that the crypto/sha1 package also has a handy sha1.Sum() function which does this in one step:

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

Output is the same. Try it on the Go Playground.

答案2

得分: 3

这是一个示例,展示了如何正确使用它。你应该这样做:

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

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

英文:

There is an example of how to use it properly. You should do:

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

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

huangapple
  • 本文由 发表于 2017年7月27日 18:18:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/45347894.html
匿名

发表评论

匿名网友

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

确定