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
+22.4k Golang : Strings to lowercase and uppercase example
+7.5k Golang : Reverse a string with unicode
+9.7k Golang : Convert octal value to string to deal with leading zero problem
+9.8k Golang : Read file and convert content to string
+19.7k Swift : Convert (cast) Int to int32 or Uint32
+10.4k Golang : Underscore string example
+14.2k Golang : Find network of an IP address
+6.8k Golang : Squaring elements in array
+11.8k Golang : Get remaining text such as id or filename after last segment in URL path
+8.8k Golang : How to use Gorilla webtoolkit context package properly
+28.9k Golang : Record voice(audio) from microphone to .WAV file
+16.6k Golang : How to generate QR codes?