diff --git a/encryption/encryption.go b/encryption/encryption.go index a940f01037d19ffd8016d76c8029a5a7e2b16cd4..cda03b47ea8d3c7802c44c2fdcbd9d6a2655bf3d 100644 --- a/encryption/encryption.go +++ b/encryption/encryption.go @@ -8,6 +8,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/base64" + "encoding/json" "fmt" "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors" "io" @@ -26,6 +27,68 @@ func Md5HashString(bytesToHash []byte) string { return hashString } +func EncryptStruct(object any, key string) (string, error) { + if len(key) != 32 { + return "", errors.New("key should be 32 bytes") + } + + block, err := aes.NewCipher([]byte(key)) + if err != nil { + return "", err + } + + aesGcm, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + + nonce := make([]byte, aesGcm.NonceSize()) + if _, err = io.ReadFull(rand.Reader, nonce); err != nil { + return "", err + } + + jsonValue, err := json.Marshal(object) + if err != nil { + return "", err + } + + encryptedValue := string(aesGcm.Seal(nonce, nonce, jsonValue, nil)) + return base64.StdEncoding.EncodeToString([]byte(encryptedValue)), nil +} + +func DecryptStruct(encryptedStruct string, key string, object any) error { + if len(key) != 32 { + return errors.New("key should be 32 bytes") + } + + decodedStruct, _ := base64.StdEncoding.DecodeString(encryptedStruct) + decodedStructString := string(decodedStruct) + + block, err := aes.NewCipher([]byte(key)) + if err != nil { + return err + } + + aesGcm, err := cipher.NewGCM(block) + if err != nil { + return err + } + + nonceSize := aesGcm.NonceSize() + if len(decodedStructString) < nonceSize { + return errors.New("ciphertext too short") + } + + nonce, ciphertext := decodedStructString[:nonceSize], decodedStructString[nonceSize:] + value, err := aesGcm.Open(nil, []byte(nonce), []byte(ciphertext), nil) + + err = json.Unmarshal(value, object) + if err != nil { + return err + } + return nil +} + func Encrypt(plaintext string, key string) (string, error) { if len(key) != 32 { return "", errors.New("key should be 32 bytes")