github.com/ystia/yorc/v4@v4.3.0/storage/encryption/encryption.go (about) 1 // Copyright 2019 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package encryption 16 17 import ( 18 "crypto/aes" 19 "crypto/cipher" 20 "crypto/rand" 21 "encoding/hex" 22 "io" 23 24 "github.com/pkg/errors" 25 ) 26 27 // Encryptor allows to encrypt/Decrypt any date with AES tools 28 type Encryptor struct { 29 Key string // encryption 256-bits key encoded in hexadecimal 30 gcm cipher.AEAD 31 } 32 33 // NewEncryptor allows to instantiate a new encryptor with an existing key or a new one if no key is provided 34 func NewEncryptor(key string) (*Encryptor, error) { 35 if key == "" { 36 return nil, errors.Errorf("missing encryption key") 37 } 38 // Build GCM for all encryption/decryption 39 decoded, err := hex.DecodeString(key) 40 if err != nil { 41 return nil, errors.Wrapf(err, "failed to decode hexadecimal key") 42 } 43 block, err := aes.NewCipher(decoded) 44 if err != nil { 45 return nil, errors.Wrapf(err, "failed to instantiate new cipher block") 46 } 47 gcm, err := cipher.NewGCM(block) 48 if err != nil { 49 return nil, errors.Wrapf(err, "failed to instantiate new cipher GCM") 50 } 51 return &Encryptor{ 52 Key: key, 53 gcm: gcm, 54 }, nil 55 } 56 57 // Encrypt allows to encrypt data with the encryptor GCM 58 // encrypted data is prefixed with the nonce 59 func (e *Encryptor) Encrypt(data []byte) ([]byte, error) { 60 nonce := make([]byte, e.gcm.NonceSize()) 61 if _, err := io.ReadFull(rand.Reader, nonce); err != nil { 62 return nil, errors.Wrapf(err, "failed to read nonce from cipher GCM") 63 } 64 return e.gcm.Seal(nonce, nonce, data, nil), nil 65 } 66 67 // Decrypt allows to decrypt previously encrypted data 68 // We need to retrieve the nonce defined as the encrypted data prefix 69 func (e *Encryptor) Decrypt(data []byte) ([]byte, error) { 70 nonceSize := e.gcm.NonceSize() 71 nonce, encrypted := data[:nonceSize], data[nonceSize:] 72 decrypted, err := e.gcm.Open(nil, nonce, encrypted, nil) 73 if err != nil { 74 return nil, errors.Wrapf(err, "failed to decrypt data from cipher GCM") 75 } 76 return decrypted, nil 77 }