package user import ( "crypto/rand" "encoding/base64" "fmt" "golang.org/x/crypto/argon2" ) type Secret struct { Raw string hash string } func (s Secret) HashSecret() error { hashconf := &struct { memory uint32 iterations uint32 parallelism uint8 keyLength uint32 saltLength uint32 }{64 * 1024, 3, 2, 12, 16} salt := make([]byte, hashconf.saltLength) _, err := rand.Read(salt) if err != nil { return err } hash := argon2.IDKey( []byte(s.Raw), salt, hashconf.iterations, hashconf.memory, hashconf.parallelism, hashconf.keyLength, ) b64Salt := base64.RawStdEncoding.EncodeToString(salt) b64Hash := base64.RawStdEncoding.EncodeToString(hash) encodedHash := fmt.Sprintf( "$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", argon2.Version, hashconf.memory, hashconf.iterations, hashconf.parallelism, b64Salt, b64Hash, ) s.hash = encodedHash return err } func (s *Secret) Hash() string { return s.hash }