add vendoring
This commit is contained in:
80
vendor/github.com/raja/argon2pw/argon2pw.go
generated
vendored
Normal file
80
vendor/github.com/raja/argon2pw/argon2pw.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
package argon2pw
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/argon2"
|
||||
)
|
||||
|
||||
const (
|
||||
passwordType = "argon2id"
|
||||
saltLen = 32
|
||||
argon2KeyLen = 32
|
||||
argon2Time = 1
|
||||
argon2Memory = 64 * 1024
|
||||
)
|
||||
|
||||
var argon2Threads = uint8(runtime.NumCPU())
|
||||
|
||||
// GenerateSaltedHash takes a plaintext password and generates an argon2 hash
|
||||
func GenerateSaltedHash(password string) (string, error) {
|
||||
if len(password) == 0 {
|
||||
return "", errors.New("Password length cannot be 0")
|
||||
}
|
||||
salt, _ := generateSalt(saltLen)
|
||||
unencodedPassword := argon2.IDKey([]byte(password), []byte(salt), argon2Time, argon2Memory, argon2Threads, argon2KeyLen)
|
||||
encodedPassword := base64.StdEncoding.EncodeToString(unencodedPassword)
|
||||
hash := fmt.Sprintf("%s$%d$%d$%d$%d$%s$%s",
|
||||
passwordType, argon2Time, argon2Memory, argon2Threads, argon2KeyLen, salt, encodedPassword)
|
||||
|
||||
return hash, nil
|
||||
}
|
||||
|
||||
// CompareHashWithPassword compares an argon2 hash against plaintext password
|
||||
func CompareHashWithPassword(hash, password string) (bool, error) {
|
||||
if len(hash) == 0 || len(password) == 0 {
|
||||
return false, errors.New("Arguments cannot be zero length")
|
||||
}
|
||||
hashParts := strings.Split(hash, "$")
|
||||
if len(hashParts) != 7 {
|
||||
return false, errors.New("Invalid Password Hash")
|
||||
}
|
||||
|
||||
passwordType := hashParts[0]
|
||||
time, _ := strconv.Atoi((hashParts[1]))
|
||||
memory, _ := strconv.Atoi(hashParts[2])
|
||||
threads, _ := strconv.Atoi(hashParts[3])
|
||||
keyLen, _ := strconv.Atoi(hashParts[4])
|
||||
salt := []byte(hashParts[5])
|
||||
key, _ := base64.StdEncoding.DecodeString(hashParts[6])
|
||||
|
||||
var calculatedKey []byte
|
||||
switch passwordType {
|
||||
case "argon2id":
|
||||
calculatedKey = argon2.IDKey([]byte(password), salt, uint32(time), uint32(memory), uint8(threads), uint32(keyLen))
|
||||
case "argon2i", "argon2":
|
||||
calculatedKey = argon2.Key([]byte(password), salt, uint32(time), uint32(memory), uint8(threads), uint32(keyLen))
|
||||
default:
|
||||
return false, errors.New("Invalid Password Hash")
|
||||
}
|
||||
|
||||
if subtle.ConstantTimeCompare(key, calculatedKey) != 1 {
|
||||
return false, errors.New("Password did not match")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func generateSalt(len int) (string, error) {
|
||||
unencodedSalt := make([]byte, len)
|
||||
if _, err := rand.Read(unencodedSalt); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(unencodedSalt), nil
|
||||
}
|
||||
Reference in New Issue
Block a user