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

Java
1package main 2 3import ( 4 "crypto/rand" 5 "crypto/sha512" 6 "encoding/base64" 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 base64 encoded 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 base64 encoded string 48 var base64EncodedPasswordHash = 49 base64.URLEncoding.EncodeToString(hashedPasswordBytes) 50 51 return base64EncodedPasswordHash 52} 53 54// Check if two passwords match 55func doPasswordsMatch(hashedPassword, currPassword string, 56 salt []byte) bool { 57 var currPasswordHash = hashPassword(currPassword, salt) 58 59 return hashedPassword == currPasswordHash 60} 61 62func main() { 63 // First generate random 16 byte salt 64 var salt = generateRandomSalt(saltSize) 65 66 // Hash password using the salt 67 var hashedPassword = hashPassword("hello", salt) 68 69 fmt.Println("Password Hash:", hashedPassword) 70 fmt.Println("Salt:", salt) 71 72 // Check if passed password matches the original password by hashing it 73 // with the original password's salt and check if the hashes match 74 fmt.Println("Password Match:", 75 doPasswordsMatch(hashedPassword, "hello", salt)) 76}
Markdown
1Password Hash: A35RZYYzKg3ORfktK3l2x204AEvF_U23x1liLeLDmcxHRr1K_DTUyXRM5-ESkb-Gr5FO2eX91pD4OWFtWmjbIg== 2Salt: [7 20 118 194 45 247 47 37 106 90 251 54 144 36 7 124] 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