62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
// Copyright 2024 Patial Tech (Ankit Patial).
|
|
//
|
|
// This file is part of code.patial.tech/go/appcore, which is MIT licensed.
|
|
// See http://opensource.org/licenses/MIT
|
|
|
|
package crypto
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
|
|
"golang.org/x/crypto/argon2"
|
|
)
|
|
|
|
const (
|
|
a2KeyMem = 19456 // 1024*19
|
|
a2KeyLen = 32
|
|
)
|
|
|
|
func argon2Hash(pwd, salt []byte) []byte {
|
|
// https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
|
// m=19456 (19 MiB), t=2, p=1
|
|
return argon2.IDKey(pwd, salt, 2, a2KeyMem, 1, a2KeyLen)
|
|
}
|
|
|
|
// PasswordHash using Argon2id
|
|
//
|
|
// https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id
|
|
func PasswordHash(pwd string) (hash, salt string, err error) {
|
|
var sl []byte
|
|
sl, err = RandomBytes(a2KeyLen)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// Generate hash
|
|
h := argon2Hash([]byte(pwd), sl)
|
|
hash = base64.StdEncoding.EncodeToString(h)
|
|
salt = base64.StdEncoding.EncodeToString(sl)
|
|
return
|
|
}
|
|
|
|
func ComparePasswordHash(pwd, hash, salt string) (bool, error) {
|
|
var h, s []byte
|
|
var err error
|
|
|
|
if h, err = base64.StdEncoding.DecodeString(hash); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if s, err = base64.StdEncoding.DecodeString(salt); err != nil {
|
|
return false, err
|
|
}
|
|
|
|
// Generate hash for comparison.
|
|
ph := argon2Hash([]byte(pwd), s)
|
|
|
|
// Compare the generated hash with the stored hash.
|
|
// If they don't match return error.
|
|
return bytes.Equal(h, ph), nil
|
|
}
|