Skip to content

Instantly share code, notes, and snippets.

@saggit
Created June 14, 2015 12:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saggit/19c4404e9a20d54fdcf1 to your computer and use it in GitHub Desktop.
Save saggit/19c4404e9a20d54fdcf1 to your computer and use it in GitHub Desktop.
Go implement werkzeug generate_password_hash check_password_hash with help of golang.org/x/crypto/pbkdf2 package
package main
import (
"crypto/rand"
"crypto/sha1"
"encoding/hex"
"fmt"
"golang.org/x/crypto/pbkdf2"
"strings"
)
var (
method = "pbkdf2:sha1"
salt_length = 8
iterations = 1000
SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
func gen_salt() string {
var bytes = make([]byte, salt_length)
rand.Read(bytes)
for k, v := range bytes {
bytes[k] = SALT_CHARS[v%byte(len(SALT_CHARS))]
}
return string(bytes)
}
func hash_internal(salt string, password string) string {
hash := pbkdf2.Key([]byte(password), []byte(salt), iterations, 20, sha1.New)
return hex.EncodeToString(hash)
}
func generate_password_hash(password string) string {
salt := gen_salt()
hash := hash_internal(salt, password)
return fmt.Sprintf("pbkdf2:sha1:%v$%s$%s", iterations, salt, hash)
}
func check_password_hash(password string, hash string) bool {
if strings.Count(hash, "$") < 2 {
return false
}
pwd_hash_list := strings.Split(hash, "$")
return pwd_hash_list[2] == hash_internal(pwd_hash_list[1], password)
}
func main() {
// var pwd = generate_password_hash("123")
// fmt.Println(pwd)
// fmt.Println("pbkdf2:sha1:1000$OInhhke2$755609e03bc57149461fcf775779948495a6874c")
// fmt.Println(check_password_hash("123", pwd))
fmt.Println(check_password_hash("123", "pbkdf2:sha1:1000$OInhhke2$755609e03bc57149461fcf775779948495a6874c"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment