github.com/Axway/agent-sdk@v1.1.101/pkg/util/gcmencrypt.go (about) 1 package util 2 3 import ( 4 "crypto/aes" 5 "crypto/cipher" 6 "crypto/rand" 7 "crypto/sha256" 8 "encoding/base64" 9 "io" 10 ) 11 12 // gcmEncryption implements the Encryptor/Decryptor interface 13 type gcmEncoder struct { 14 gcm cipher.AEAD 15 } 16 17 func newGCMEncoder(key []byte) (*gcmEncoder, error) { 18 block, err := aes.NewCipher(hashedKey(key)) 19 if err != nil { 20 return nil, err 21 } 22 23 gcm, err := cipher.NewGCM(block) 24 if err != nil { 25 return nil, err 26 } 27 enc := &gcmEncoder{ 28 gcm: gcm, 29 } 30 return enc, nil 31 } 32 33 func hashedKey(key []byte) []byte { 34 hash := sha256.New() 35 hash.Write(key) 36 return hash.Sum(nil) 37 } 38 39 // NewGCMEncryptor creates a struct to handle encryption based on the provided key. 40 func NewGCMEncryptor(key []byte) (Encryptor, error) { 41 return newGCMEncoder(key) 42 } 43 44 // NewGCMDecryptor creates a struct to handle decryption based on the provided key. 45 func NewGCMDecryptor(key []byte) (Decryptor, error) { 46 return newGCMEncoder(key) 47 } 48 49 // Encrypt encrypts string with a secret key and returns encrypted string. 50 func (e *gcmEncoder) Encrypt(str string) (string, error) { 51 nonce := make([]byte, e.gcm.NonceSize()) 52 if _, err := io.ReadFull(rand.Reader, nonce); err != nil { 53 return "", err 54 } 55 encrypted := e.gcm.Seal(nonce, nonce, []byte(str), nil) 56 return base64.URLEncoding.EncodeToString(encrypted), nil 57 } 58 59 // Decrypt decrypts encrypted string with a secret key and returns plain string. 60 func (e *gcmEncoder) Decrypt(str string) (string, error) { 61 ed, err := base64.URLEncoding.DecodeString(str) 62 if err != nil { 63 return "", err 64 } 65 66 nonceSize := e.gcm.NonceSize() 67 if len(ed) < nonceSize { 68 return "", err 69 } 70 71 nonce, cipherText := ed[:nonceSize], ed[nonceSize:] 72 decrypted, err := e.gcm.Open(nil, nonce, cipherText, nil) 73 if err != nil { 74 return "", err 75 } 76 77 return string(decrypted), nil 78 }