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