SHA stands for secure hashing algorithm. SHA is a modified version of MD5 and used for hashing data and certificates. Hashing and encryption are similar; the only difference is that hashing is one-way, meaning that after the data has been hashed, the resulting hash digest cannot be decrypted. When talking about SHA forms, several different types of SHA are referenced (SHA-1, SHA-2, SHA-256, SHA-512, SHA-224, and SHA-384,...). Sha256 is part of the SHA-2 family of hash functions and uses a 256-bit key to take a piece of data and convert it into a new, unrecognizable data string of a fixed length. SHA256 has 32 bits internal block size.
We hash some messages in the below example:
In this article, we will learn about how to hash data in Golang
Hashing data in Golang using package hash265
Package sha256 implements the SHA224 and SHA256 hash algorithms as defined in FIPS 180-4.
Some functions can be used to hash data:
func New() hash.Hash
: New returns a new hash.Hash computing the SHA256 checksum. The Hash also implements encoding.BinaryMarshaler
and encoding.BinaryUnmarshaler
to marshal and unmarshal the internal state of the hash.
func Sum256(data []byte) [Size]byte
: Sum256 returns the SHA256 checksum of the data.
Method-1: Using sha256.New()
Example of using New() hash.Hash
function:
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
h := sha256.New()
h.Write([]byte("this is a password"))
// Calculate and print the hash
fmt.Printf("%x", h.Sum(nil))
}
Output:
289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e
Explanation:
- Create a new sha256 hasher
- Pass string to the hasher
- Calculate and return hash
Method-2: Using sha256.Sum256()
Example of using sha256.Sum256()
function:
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
sum := sha256.Sum256([]byte("this is a password"))
fmt.Printf("%x", sum)
}
Output:
289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e
In the next example notice that even when two strings differ by only one capital letter, the hashes generated are completely different.
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
sum := sha256.Sum256([]byte("this is a password"))
sumCap := sha256.Sum256([]byte("This is a password"))
fmt.Printf("lowercase hash: %x", sum)
fmt.Println("")
fmt.Printf("Capital hash: %x", sumCap)
}
Output:
lowercase hash: 289ca48885442b5480dd76df484e1f90867a2961493b7c60e542e84addce5d1e
Capital hash: 9ae12b1403d242c53b0ea80137de34856b3495c3c49670aa77c7ec99eadbba6e
Using sha256 package to hash File or Input stream
We may have a requirement to watch a file for some changes. A standard implementation uses a time.Ticker to recalculate a hash of your configuration file every few seconds and reload if the hash changes.
To compute the hash value of a file or other input stream:
- Open and read the file
- Create a new
hash.Hash
fromÂcrypto/sha256
- Parse the file's content to the hasher
- Call the Sum function to get the checksum.
Example of hashing a file:
package main
import (
"crypto/sha256"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("test") // Open the file for reading
if err != nil {
panic(err)
}
defer file.Close() // Be sure to close your file!
hash := sha256.New() // Use the Hash in crypto/sha256
if _, err := io.Copy(hash, file); err != nil {
panic(err)
}
sum := fmt.Sprintf("%x", hash.Sum(nil)) // Get encoded hash sum
fmt.Println(sum)
}
Here I have a file "test" with some content and I will create a hash for this file.
# go run main.go
b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
Summary
The specifications for data encryption algorithms are complex and, in most cases, the subject of extensive research. Golang, on the other hand, has a dedicated library that implements a number of popular cryptographic algorithms as functions. In this article, I have demonstrate how to use crypto/sha256
package to generate hash for a string, a file or a input stream.
References
https://pkg.go.dev/crypto/sha256