Golang : Securing password with salt
Every now and then we will hear some companies or banks database got compromised and the hackers will publish the login username and password in plaintext. Storing passwords in plaintext is a big no-no and developers must take effort to ensure that the passwords are at least "salted" before storing into database.
In the event of leaking by insider or hacking.... at least the passwords are not visible and require significant effort to turn them into plaintext.
This tutorial will demonstrate :
- how to generate salt and password hash with sha1 crypto from a given password(such as during registration)
- simulate login to compare different passwords. One is wrong and one is correct.
and here is the Golang code :
package main
import (
"bytes"
"fmt"
"io"
"os"
"crypto/rand"
"crypto/sha1"
)
const saltSize = 16
func generateSalt(secret []byte) []byte {
buf := make([]byte, saltSize, saltSize+sha1.Size)
_, err := io.ReadFull(rand.Reader, buf)
if err != nil {
fmt.Printf("random read failed: %v", err)
os.Exit(1)
}
hash := sha1.New()
hash.Write(buf)
hash.Write(secret)
return hash.Sum(buf)
}
func main() {
// during registration
// user password is hello
password := []byte("hello")
fmt.Println("Password : ", string(password))
// generate salt from given password
salt := generateSalt(password)
fmt.Printf("Salt : %x \n", salt)
// generate password + salt hash to store into database
combination := string(salt) + string(password)
passwordHash := sha1.New()
io.WriteString(passwordHash, combination)
fmt.Printf("Password Hash : %x \n", passwordHash.Sum(nil))
// later on ...
// during login, retrieve passwordHash and salt from database
// test wrong password
wrongPassword := []byte("bye") // this is the password from login page
wrongCombination := string(salt) + string(wrongPassword)
wrongHash := sha1.New()
io.WriteString(wrongHash, wrongCombination)
fmt.Printf("%x \n", wrongHash.Sum(nil))
fmt.Printf("%x \n", passwordHash.Sum(nil))
match := bytes.Equal(wrongHash.Sum(nil), passwordHash.Sum(nil))
fmt.Printf("Login successful ? : %v\n", match)
// test correct password
correctPassword := []byte("hello") // this is the password from login page
correctCombination := string(salt) + string(correctPassword)
correctHash := sha1.New()
io.WriteString(correctHash, correctCombination)
fmt.Printf("%x \n", correctHash.Sum(nil))
fmt.Printf("%x \n", passwordHash.Sum(nil))
match = bytes.Equal(correctHash.Sum(nil), passwordHash.Sum(nil))
fmt.Printf("Login successful ? : %v\n", match)
}
Sample output :
>go run saltingpassword.go
Password : hello
Salt : 91c9c1884ffbccba875e2885cd56d06d5131d08eee748ada0bb841d15528f581adb9e72b
Password Hash : 7cbe266f3bc39e9076e4f3e6cc40955f09339fac
a73912fadf914bc8a1bb4feb67a15d85d7e27e32
7cbe266f3bc39e9076e4f3e6cc40955f09339fac
Login successful ? : false
7cbe266f3bc39e9076e4f3e6cc40955f09339fac
7cbe266f3bc39e9076e4f3e6cc40955f09339fac
Login successful ? : true
That's it. Simplest way to secure password since .... the 70s I reckon. Hope this tutorial can be useful to you.
See also : Golang : Bcrypting password
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+11.2k Golang : Find age or leap age from date of birth example
+9.5k Golang : ffmpeg with os/exec.Command() returns non-zero status
+44.4k Golang : Use wildcard patterns with filepath.Glob() example
+36.1k Golang : Convert date or time stamp from string to time.Time type
+19.8k Golang : Compare floating-point numbers
+14.9k Golang : Accurate and reliable decimal calculations
+16.5k Golang : Get the IPv4 and IPv6 addresses for a specific network interface
+22.5k Golang : simulate tail -f or read last line from log file example
+10.9k Golang : How to determine a prime number?
+13.1k Golang : Increment string example
+12k Golang : How to check if a string starts or ends with certain characters or words?
+5.7k Golang : Denco multiplexer example