github.com/annwntech/go-micro/v2@v2.9.5/config/secrets/secretbox/secretbox.go (about)

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