github.com/micro/go-micro/v2@v2.9.1/tunnel/crypto.go (about) 1 package tunnel 2 3 import ( 4 "crypto/aes" 5 "crypto/cipher" 6 "crypto/rand" 7 "crypto/sha256" 8 9 "github.com/oxtoacart/bpool" 10 ) 11 12 var ( 13 // the local buffer pool 14 // gcmStandardNonceSize from crypto/cipher/gcm.go is 12 bytes 15 // 100 - is max size of pool 16 noncePool = bpool.NewBytePool(100, 12) 17 ) 18 19 // hash hahes the data into 32 bytes key and returns it 20 // hash uses sha256 underneath to hash the supplied key 21 func hash(key []byte) []byte { 22 sum := sha256.Sum256(key) 23 return sum[:] 24 } 25 26 // Encrypt encrypts data and returns the encrypted data 27 func Encrypt(gcm cipher.AEAD, data []byte) ([]byte, error) { 28 var err error 29 30 // get new byte array the size of the nonce from pool 31 // NOTE: we might use smaller nonce size in the future 32 nonce := noncePool.Get() 33 if _, err = rand.Read(nonce); err != nil { 34 return nil, err 35 } 36 defer noncePool.Put(nonce) 37 38 // NOTE: we prepend the nonce to the payload 39 // we need to do this as we need the same nonce 40 // to decrypt the payload when receiving it 41 return gcm.Seal(nonce, nonce, data, nil), nil 42 } 43 44 // Decrypt decrypts the payload and returns the decrypted data 45 func newCipher(key []byte) (cipher.AEAD, error) { 46 var err error 47 48 // generate a new AES cipher using our 32 byte key for decrypting the message 49 c, err := aes.NewCipher(hash(key)) 50 if err != nil { 51 return nil, err 52 } 53 54 // gcm or Galois/Counter Mode, is a mode of operation 55 // for symmetric key cryptographic block ciphers 56 // - https://en.wikipedia.org/wiki/Galois/Counter_Mode 57 gcm, err := cipher.NewGCM(c) 58 if err != nil { 59 return nil, err 60 } 61 62 return gcm, nil 63 } 64 65 func Decrypt(gcm cipher.AEAD, data []byte) ([]byte, error) { 66 var err error 67 68 nonceSize := gcm.NonceSize() 69 70 if len(data) < nonceSize { 71 return nil, ErrDecryptingData 72 } 73 74 // NOTE: we need to parse out nonce from the payload 75 // we prepend the nonce to every encrypted payload 76 nonce, ciphertext := data[:nonceSize], data[nonceSize:] 77 ciphertext, err = gcm.Open(ciphertext[:0], nonce, ciphertext, nil) 78 if err != nil { 79 return nil, err 80 } 81 82 return ciphertext, nil 83 }