package shared import ( "bytes" "compress/flate" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "fmt" "io" ) type EncryptionClient interface { Encrypt(string) (string, error) Decrypt(string) (string, error) } type encryptionClient struct { Secret string } func NewEncryptionClient(secret string) EncryptionClient { return &encryptionClient{Secret: secret} } func compress(text string) ([]byte, error) { var compressedBytes bytes.Buffer w, err := flate.NewWriter(&compressedBytes, flate.BestCompression) w.Write([]byte(text)) w.Close() return compressedBytes.Bytes(), err } func decompress(compressedBytes []byte) (string, error) { reader := flate.NewReader(bytes.NewReader(compressedBytes)) defer reader.Close() textBytes := new(bytes.Buffer) _, err := textBytes.ReadFrom(reader) return textBytes.String(), err } // Encrypt method is to encrypt or hide any classified text func (e encryptionClient) Encrypt(text string) (string, error) { block, err := aes.NewCipher([]byte(e.Secret)) if err != nil { return "", err } compressedText, err := compress(text) if err != nil { return "", err } gcm, err := cipher.NewGCM(block) if err != nil { return "", err } bytes := make([]byte, gcm.NonceSize()) if _, err = io.ReadFull(rand.Reader, bytes); err != nil { return "", err } encodedText := gcm.Seal(bytes, bytes, compressedText, nil) return base64.StdEncoding.EncodeToString(encodedText), nil } // Decrypt method is to extract back the encrypted text func (e encryptionClient) Decrypt(text string) (string, error) { block, err := aes.NewCipher([]byte(e.Secret)) if err != nil { return "", err } cipherText, err := base64.StdEncoding.DecodeString(text) if err != nil { return "", err } gcm, err := cipher.NewGCM(block) if err != nil { return "", err } if len(cipherText) < gcm.NonceSize() { return "", fmt.Errorf("text is too small") } bytes, cipherText := cipherText[:gcm.NonceSize()], cipherText[gcm.NonceSize():] compressedTextBytes, err := gcm.Open(nil, bytes, cipherText, nil) if err != nil { return "", err } return decompress(compressedTextBytes) }