Golang

How to Hash and Salt Passwords in Golang Using SHA-512 and Why You Shouldn’t

Hashing and salting passwords is an industry standard for protecting passwords for any respectable service.

Written by Gregory Gaines
1 min read
0 views
Vault door
Photo by Jason Dent on Unsplash

Table of Contents

Hashing and salting passwords is an industry standard for protecting passwords for any respectable service. One option is using SHA-512 that computes quickly. The downside is attackers can take advantage of this with computational power.

Using Bcrypt is a better option

Algorithms like SHA are fast and efficient, allowing attackers to quickly brute force a password match. Not a very good choice for security, luckily there is another hashing algorithm called Bcrypt which is designed for hashing passwords slowly. This frustrates attackers because passwords can't be brute forced and an increase in computational power will do little to help. Learn more on my article on hashing passwords with Bcrypt.

Hashing Steps

  1. Convert password string to a byte slice

  2. Generate random salt of 16 bytes (SHA2-crypt methods in Linus, BSD Unixes, and Solaris use 16 bytes)

  3. Append salt to password slice

  4. Hash resulting concatenation

Implementation

Go
1package main 2 3import ( 4 "crypto/rand" 5 "crypto/sha512" 6 "encoding/hex" 7 "fmt" 8) 9 10// Define salt size 11const saltSize = 16 12 13// Generate 16 bytes randomly and securely using the 14// Cryptographically secure pseudorandom number generator (CSPRNG) 15// in the crypto.rand package 16func generateRandomSalt(saltSize int) []byte { 17 var salt = make([]byte, saltSize) 18 19 _, err := rand.Read(salt[:]) 20 21 if err != nil { 22 panic(err) 23 } 24 25 return salt 26} 27 28// Combine password and salt then hash them using the SHA-512 29// hashing algorithm and then return the hashed password 30// as a hex string 31func hashPassword(password string, salt []byte) string { 32 // Convert password string to byte slice 33 var passwordBytes = []byte(password) 34 35 // Create sha-512 hasher 36 var sha512Hasher = sha512.New() 37 38 // Append salt to password 39 passwordBytes = append(passwordBytes, salt...) 40 41 // Write password bytes to the hasher 42 sha512Hasher.Write(passwordBytes) 43 44 // Get the SHA-512 hashed password 45 var hashedPasswordBytes = sha512Hasher.Sum(nil) 46 47 // Convert the hashed password to a hex string 48 var hashedPasswordHex = hex.EncodeToString(hashedPasswordBytes) 49 50 return hashedPasswordHex 51} 52 53// Check if two passwords match 54func doPasswordsMatch(hashedPassword, currPassword string, 55 salt []byte) bool { 56 var currPasswordHash = hashPassword(currPassword, salt) 57 58 return hashedPassword == currPasswordHash 59} 60 61func main() { 62 // First generate random 16 byte salt 63 var salt = generateRandomSalt(saltSize) 64 65 // Hash password using the salt 66 var hashedPassword = hashPassword("hello", salt) 67 68 fmt.Println("Password Hash:", hashedPassword) 69 fmt.Println("Salt:", salt) 70 71 // Check if passed password matches the original password by hashing it 72 // with the original password's salt and check if the hashes match 73 fmt.Println("Password Match:", 74 doPasswordsMatch(hashedPassword, "hello", salt)) 75}
Markdown
1Password Hash: c7b714330211d3eddd0b047cde89b6ce618f321532eeb6ebbd0974c0d92097a66a2264a9b42012eb3387fe91f217e2109f2eefa26ee24a9c33e5417365bf07ec 2Salt: [192 42 57 120 177 235 67 200 75 110 215 162 5 44 205 20] 3Password Match: true

Consider signing up for my newsletter or supporting me if this was helpful. Thanks for reading!

About the author.

I'm Gregory Gaines, a software engineer that loves blogging, studying computer science, and reverse engineering.

I'm currently employed at Google; all opinions are my own.

Ko-fi donationsBuy Me a CoffeeBecome a Patron
Gregory Gaines

You may also like.

Comments.

Get updates straight to your mailbox!

Get the latest blog updates about programming and the industry ins and outs for free!

You have my spam free, guarantee. 🥳

Subscribe