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
+26.3k Golang : How to check if a connection to database is still alive ?
+17.8k Golang : Aligning strings to right, left and center with fill example
+5.8k Golang : Get missing location after unmarshal binary and gob decode time.
+7.5k Javascript : Put image into Chrome browser's console
+5.2k Golang : Detect words using using consecutive letters in a given string
+8.4k Golang : Gaussian blur on image and camera video feed examples
+25.2k Golang : Convert IP address string to long ( unsigned 32-bit integer )
+7.8k Golang : Routes multiplexer routing example with regular expression control
+19.2k Golang : Measure http.Get() execution time
+8.7k Golang : Serving HTTP and Websocket from different ports in a program example
+21.6k Golang : Match strings by wildcard patterns with filepath.Match() function