crypto.go (1698B)
1 package crypto 2 3 import ( 4 "cerca/util" 5 crand "crypto/rand" 6 "encoding/binary" 7 "github.com/matthewhartstonge/argon2" 8 "math/big" 9 rand "math/rand" 10 "strings" 11 ) 12 13 func HashPassword(s string) (string, error) { 14 ed := util.Describe("hash password") 15 config := argon2.MemoryConstrainedDefaults() 16 hash, err := config.HashEncoded([]byte(s)) 17 if err != nil { 18 return "", ed.Eout(err, "hashing with argon2id") 19 } 20 return string(hash), nil 21 } 22 23 func ValidatePasswordHash(password, passwordHash string) bool { 24 ed := util.Describe("validate password hash") 25 hashStruct, err := argon2.Decode([]byte(passwordHash)) 26 ed.Check(err, "argon2.decode") 27 correct, err := hashStruct.Verify([]byte(password)) 28 if err != nil { 29 return false 30 } 31 return correct 32 } 33 34 // used for generating a random reset password 35 const characterSet = "abcdedfghijklmnopqrstABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 36 const pwlength = 20 37 38 func GeneratePassword() string { 39 var password strings.Builder 40 const maxChar = int64(len(characterSet)) 41 42 for i := 0; i < pwlength; i++ { 43 max := big.NewInt(maxChar) 44 bigN, err := crand.Int(crand.Reader, max) 45 util.Check(err, "randomly generate int") 46 n := bigN.Int64() 47 password.WriteString(string(characterSet[n])) 48 } 49 return password.String() 50 } 51 52 func GenerateVerificationCode() int { 53 var src cryptoSource 54 rnd := rand.New(src) 55 return rnd.Intn(999999) 56 } 57 58 type cryptoSource struct{} 59 60 func (s cryptoSource) Seed(seed int64) {} 61 62 func (s cryptoSource) Int63() int64 { 63 return int64(s.Uint64() & ^uint64(1<<63)) 64 } 65 66 func (s cryptoSource) Uint64() (v uint64) { 67 err := binary.Read(crand.Reader, binary.BigEndian, &v) 68 if err != nil { 69 util.Check(err, "generate random verification code") 70 } 71 return v 72 }