secretbox.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Package secretbox is a config/secrets implementation that uses nacl/secretbox
  2. // to do symmetric encryption / verification
  3. package secretbox
  4. import (
  5. "github.com/pkg/errors"
  6. "gogs.baozhida.cn/zoie/OAuth-core/config/secrets"
  7. "golang.org/x/crypto/nacl/secretbox"
  8. "crypto/rand"
  9. )
  10. const keyLength = 32
  11. type secretBox struct {
  12. options secrets.Options
  13. secretKey [keyLength]byte
  14. }
  15. // NewSecrets returns a secretbox codec
  16. func NewSecrets(opts ...secrets.Option) secrets.Secrets {
  17. sb := &secretBox{}
  18. for _, o := range opts {
  19. o(&sb.options)
  20. }
  21. return sb
  22. }
  23. func (s *secretBox) Init(opts ...secrets.Option) error {
  24. for _, o := range opts {
  25. o(&s.options)
  26. }
  27. if len(s.options.Key) == 0 {
  28. return errors.New("no secret key is defined")
  29. }
  30. if len(s.options.Key) != keyLength {
  31. return errors.Errorf("secret key must be %d bytes long", keyLength)
  32. }
  33. copy(s.secretKey[:], s.options.Key)
  34. return nil
  35. }
  36. func (s *secretBox) Options() secrets.Options {
  37. return s.options
  38. }
  39. func (s *secretBox) String() string {
  40. return "nacl-secretbox"
  41. }
  42. func (s *secretBox) Encrypt(in []byte, opts ...secrets.EncryptOption) ([]byte, error) {
  43. // no opts are expected, so they are ignored
  44. // there must be a unique nonce for each message
  45. var nonce [24]byte
  46. if _, err := rand.Reader.Read(nonce[:]); err != nil {
  47. return []byte{}, errors.Wrap(err, "couldn't obtain a random nonce from crypto/rand")
  48. }
  49. return secretbox.Seal(nonce[:], in, &nonce, &s.secretKey), nil
  50. }
  51. func (s *secretBox) Decrypt(in []byte, opts ...secrets.DecryptOption) ([]byte, error) {
  52. // no options are expected, so they are ignored
  53. var decryptNonce [24]byte
  54. copy(decryptNonce[:], in[:24])
  55. decrypted, ok := secretbox.Open(nil, in[24:], &decryptNonce, &s.secretKey)
  56. if !ok {
  57. return []byte{}, errors.New("decryption failed (is the key set correctly?)")
  58. }
  59. return decrypted, nil
  60. }