#pragma once #include #include #include "common/error.hpp" namespace smartbotic::crypto { // AES-256-GCM encryption result struct EncryptedData { std::vector ciphertext; std::vector iv; // 12 bytes std::vector auth_tag; // 16 bytes // Serialize to base64 encoded JSON for storage std::string toJson() const; static common::Result fromJson(const std::string& json); // Convenience for single-field storage std::string toBase64() const; static common::Result fromBase64(const std::string& encoded); }; // AES-256-GCM encryption configuration struct AesGcmConfig { std::string master_key; // Raw key or passphrase int pbkdf2_iterations = 100000; // Key derivation iterations bool use_key_derivation = true; // If false, master_key is used directly }; // AES-256-GCM authenticated encryption class AesGcm { public: explicit AesGcm(const AesGcmConfig& config); ~AesGcm() = default; // Encrypt plaintext common::Result encrypt(const std::string& plaintext); common::Result encrypt(const std::vector& plaintext); // Decrypt ciphertext common::Result decrypt(const EncryptedData& data); common::Result> decryptBytes(const EncryptedData& data); // Convenience methods for string-based storage common::Result encryptToBase64(const std::string& plaintext); common::Result decryptFromBase64(const std::string& encoded); // Generate random bytes for IV static std::vector generateRandomIv(); // Generate random key (32 bytes for AES-256) static std::string generateRandomKey(); private: // Derive encryption key from master key using PBKDF2 std::vector deriveKey(const std::vector& salt); AesGcmConfig config_; std::vector derived_key_; // Cached derived key (if not using salt per encryption) }; // Base64 encoding/decoding utilities namespace base64 { std::string encode(const std::vector& data); std::string encode(const uint8_t* data, size_t len); common::Result> decode(const std::string& encoded); } } // namespace smartbotic::crypto