Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sha1 different in go than in python and openssl

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

like image 400
minzchickenflavor Avatar asked Dec 13 '22 21:12

minzchickenflavor


1 Answers

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.

like image 135
icza Avatar answered Dec 16 '22 12:12

icza