Last active
June 13, 2020 01:30
-
-
Save ciehanski/ed4a247fe82e00a9c23ab8f72ddd723e to your computer and use it in GitHub Desktop.
Using argon2 in Golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func hashPassword(password string) (string, error) { | |
salt := make([]byte, argonSaltLen) | |
_, err := rand.Read(salt) | |
if err != nil { | |
return "", err | |
} | |
passwordHash := argon2.IDKey([]byte(password), salt, argonTime, argonMemory, argonThreads, argonKeyLen) | |
// Base64 encode the salt and hashed password | |
b64Salt := base64.RawStdEncoding.EncodeToString(salt) | |
b64Hash := base64.RawStdEncoding.EncodeToString(passwordHash) | |
// Return a string using the standard encoded hash representation | |
return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", argon2.Version, | |
argonMemory, argonTime, argonThreads, b64Salt, b64Hash), nil | |
} | |
func comparePasswordHash(expectedPassword, providedPassword string) (bool, error) { | |
vals := strings.Split(expectedPassword, "$") | |
if len(vals) != 6 { | |
return false, errors.New("invalid hash") | |
} | |
var version int | |
_, err := fmt.Sscanf(vals[2], "v=%d", &version) | |
if err != nil { | |
return false, err | |
} | |
if version != argon2.Version { | |
return false, errors.New("wrong argon version") | |
} | |
var mem, iter uint32 | |
var thread uint8 | |
_, err = fmt.Sscanf(vals[3], "m=%d,t=%d,p=%d", &mem, &iter, &thread) | |
if err != nil { | |
return false, err | |
} | |
salt, err := base64.RawStdEncoding.DecodeString(vals[4]) | |
if err != nil { | |
return false, err | |
} | |
actualPasswordHash, err := base64.RawStdEncoding.DecodeString(vals[5]) | |
if err != nil { | |
return false, err | |
} | |
providedPasswordHash := argon2.IDKey([]byte(providedPassword), salt, iter, mem, thread, | |
uint32(len(actualPasswordHash))) | |
return subtle.ConstantTimeCompare(actualPasswordHash, providedPasswordHash) == 1, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment