How to Properly Hash and Salt Passwords in Golang Using Bcrypt

The bcypt function is secure and brute force resistant allowing programmers to safely handle the passwords of their users.

Written by Gregory Gaines
1 min read
Wires plugged into server
Photo by Lars Kienle on Unsplash

Table of Contents


  • Download the golang bcrypt library using go get golang.org/x/crypto/bcrypt.


1// Hash password using the bcrypt hashing algorithm 2func hashPassword(password string) (string, error) { 3 // Convert password string to byte slice 4 var passwordBytes = []byte(password) 5 6 // Hash password with bcrypt's min cost 7 hashedPasswordBytes, err := bcrypt. 8 GenerateFromPassword(passwordBytes, bcrypt.MinCost) 9 10 return string(hashedPasswordBytes), err 11} 12 13func main() { 14 // Hash password 15 var hashedPassword, err = hashPassword("password1") 16 17 if err != nil { 18 println(fmt.Println("Error hashing password")) 19 return 20 } 21 22 fmt.Println("Password Hash:", hashedPassword) 23}

No Need to Salt Passwords

Bcrypt uses a concept named cost which represents the number of hash iterations that bcrypt undertakes. Hashing time is calculated as 2 ^ cost and the higher the cost, the longer the hashing process takes.

This deters attackers because they can't quickly brute force a password match and increasing computational power will do little to help. Bcrypt uses a variable named bcrypt.MinCost as a default cost and any cost lower defaults to bcrypt.DefaultCost.

Passwords Matching

1package main 2 3import ( 4 "fmt" 5 "golang.org/x/crypto/bcrypt" 6) 7 8// Hash password 9func hashPassword(password string) (string, error) { 10 // Convert password string to byte slice 11 var passwordBytes = []byte(password) 12 13 // Hash password with Bcrypt's min cost 14 hashedPasswordBytes, err := bcrypt. 15 GenerateFromPassword(passwordBytes, bcrypt.MinCost) 16 17 return string(hashedPasswordBytes), err 18} 19 20// Check if two passwords match using Bcrypt's CompareHashAndPassword 21// which return nil on success and an error on failure. 22func doPasswordsMatch(hashedPassword, currPassword string) bool { 23 err := bcrypt.CompareHashAndPassword( 24 []byte(hashedPassword), []byte(currPassword)) 25 return err == nil 26} 27 28func main() { 29 // Hash password 30 var hashedPassword, err = hashPassword("password1") 31 32 if err != nil { 33 println(fmt.Println("Error hashing password")) 34 return 35 } 36 37 fmt.Println("Password Hash:", hashedPassword) 38 39 // Check if passed password matches the original password 40 fmt.Println("Password Match:", 41 doPasswordsMatch(hashedPassword, "password1")) 42}
1Password Hash: $2a$04$kcsOln10l5Gm0lSgQmlrhuS0T9u124J3HfrAr9tnHltr9u7.iUsJm 2Password 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.


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. 🥳