You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

crypto.go 1.1KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. // Copyright (c) 2018 Shivaram Lingamneni <slingamn@cs.stanford.edu>
  2. // released under the MIT license
  3. package utils
  4. import (
  5. "crypto/rand"
  6. "crypto/subtle"
  7. "encoding/base32"
  8. )
  9. var (
  10. // slingamn's own private b32 alphabet, removing 1, l, o, and 0
  11. b32encoder = base32.NewEncoding("abcdefghijkmnpqrstuvwxyz23456789").WithPadding(base32.NoPadding)
  12. )
  13. const (
  14. SecretTokenLength = 26
  15. )
  16. // generate a secret token that cannot be brute-forced via online attacks
  17. func GenerateSecretToken() string {
  18. // 128 bits of entropy are enough to resist any online attack:
  19. var buf [16]byte
  20. rand.Read(buf[:])
  21. // 26 ASCII characters, should be fine for most purposes
  22. return b32encoder.EncodeToString(buf[:])
  23. }
  24. // securely check if a supplied token matches a stored token
  25. func SecretTokensMatch(storedToken string, suppliedToken string) bool {
  26. // XXX fix a potential gotcha: if the stored token is uninitialized,
  27. // then nothing should match it, not even supplying an empty token.
  28. if len(storedToken) == 0 {
  29. return false
  30. }
  31. return subtle.ConstantTimeCompare([]byte(storedToken), []byte(suppliedToken)) == 1
  32. }