box.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Package box is an asymmetric implementation of config/secrets using nacl/box
  2. package box
  3. import (
  4. "github.com/pkg/errors"
  5. "gogs.baozhida.cn/zoie/OAuth-core/config/secrets"
  6. naclbox "golang.org/x/crypto/nacl/box"
  7. "crypto/rand"
  8. )
  9. const keyLength = 32
  10. type box struct {
  11. options secrets.Options
  12. publicKey [keyLength]byte
  13. privateKey [keyLength]byte
  14. }
  15. // NewSecrets returns a nacl-box codec
  16. func NewSecrets(opts ...secrets.Option) secrets.Secrets {
  17. b := &box{}
  18. for _, o := range opts {
  19. o(&b.options)
  20. }
  21. return b
  22. }
  23. // Init initialises a box
  24. func (b *box) Init(opts ...secrets.Option) error {
  25. for _, o := range opts {
  26. o(&b.options)
  27. }
  28. if len(b.options.PrivateKey) != keyLength || len(b.options.PublicKey) != keyLength {
  29. return errors.Errorf("a public key and a private key of length %d must both be provided", keyLength)
  30. }
  31. copy(b.privateKey[:], b.options.PrivateKey)
  32. copy(b.publicKey[:], b.options.PublicKey)
  33. return nil
  34. }
  35. // Options returns options
  36. func (b *box) Options() secrets.Options {
  37. return b.options
  38. }
  39. // String returns nacl-box
  40. func (*box) String() string {
  41. return "nacl-box"
  42. }
  43. // Encrypt encrypts a message with the sender's private key and the receipient's public key
  44. func (b *box) Encrypt(in []byte, opts ...secrets.EncryptOption) ([]byte, error) {
  45. var options secrets.EncryptOptions
  46. for _, o := range opts {
  47. o(&options)
  48. }
  49. if len(options.RecipientPublicKey) != keyLength {
  50. return []byte{}, errors.New("recepient's public key must be provided")
  51. }
  52. var recipientPublicKey [keyLength]byte
  53. copy(recipientPublicKey[:], options.RecipientPublicKey)
  54. var nonce [24]byte
  55. if _, err := rand.Reader.Read(nonce[:]); err != nil {
  56. return []byte{}, errors.Wrap(err, "couldn't obtain a random nonce from crypto/rand")
  57. }
  58. return naclbox.Seal(nonce[:], in, &nonce, &recipientPublicKey, &b.privateKey), nil
  59. }
  60. // Decrypt Decrypts a message with the receiver's private key and the sender's public key
  61. func (b *box) Decrypt(in []byte, opts ...secrets.DecryptOption) ([]byte, error) {
  62. var options secrets.DecryptOptions
  63. for _, o := range opts {
  64. o(&options)
  65. }
  66. if len(options.SenderPublicKey) != keyLength {
  67. return []byte{}, errors.New("sender's public key bust be provided")
  68. }
  69. var nonce [24]byte
  70. var senderPublicKey [32]byte
  71. copy(nonce[:], in[:24])
  72. copy(senderPublicKey[:], options.SenderPublicKey)
  73. decrypted, ok := naclbox.Open(nil, in[24:], &nonce, &senderPublicKey, &b.privateKey)
  74. if !ok {
  75. return []byte{}, errors.New("incoming message couldn't be verified / decrypted")
  76. }
  77. return decrypted, nil
  78. }