< Summary

Information
Class: Orchestrator.Commands.Utility.Snapshots.SnapshotEncryptor
Assembly: Orchestrator
File(s): /home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/Snapshots/SnapshotEncryptor.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 19
Coverable lines: 19
Total lines: 60
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 2
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GenerateKey()100%210%
Encrypt(...)100%210%
ValidateKey(...)0%620%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/Snapshots/SnapshotEncryptor.cs

#LineLine coverage
 1using System.Security.Cryptography;
 2using System.Text;
 3
 4namespace Orchestrator.Commands.Utility.Snapshots;
 5
 6/// <summary>
 7/// Provides AES-256-GCM encryption for test fixtures.
 8/// This is a copy of the logic from KicktippIntegration.Tests to avoid a dependency.
 9/// </summary>
 10public static class SnapshotEncryptor
 11{
 12    private const int NonceSize = 12; // 96 bits for GCM
 13    private const int TagSize = 16;   // 128 bits for GCM
 14
 15    /// <summary>
 16    /// Generates a new random AES-256 encryption key.
 17    /// </summary>
 18    /// <returns>Base64-encoded 256-bit key.</returns>
 19    public static string GenerateKey()
 20    {
 021        var keyBytes = RandomNumberGenerator.GetBytes(32);
 022        return Convert.ToBase64String(keyBytes);
 23    }
 24
 25    /// <summary>
 26    /// Encrypts plaintext content using AES-256-GCM.
 27    /// </summary>
 28    /// <param name="plaintext">The content to encrypt.</param>
 29    /// <param name="base64Key">Base64-encoded 256-bit key.</param>
 30    /// <returns>Base64-encoded encrypted data (nonce + ciphertext + tag).</returns>
 31    public static string Encrypt(string plaintext, string base64Key)
 32    {
 033        var key = Convert.FromBase64String(base64Key);
 034        ValidateKey(key);
 35
 036        var plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
 037        var nonce = RandomNumberGenerator.GetBytes(NonceSize);
 038        var ciphertext = new byte[plaintextBytes.Length];
 039        var tag = new byte[TagSize];
 40
 041        using var aes = new AesGcm(key, TagSize);
 042        aes.Encrypt(nonce, plaintextBytes, ciphertext, tag);
 43
 44        // Combine: nonce (12) + ciphertext (variable) + tag (16)
 045        var result = new byte[NonceSize + ciphertext.Length + TagSize];
 046        Buffer.BlockCopy(nonce, 0, result, 0, NonceSize);
 047        Buffer.BlockCopy(ciphertext, 0, result, NonceSize, ciphertext.Length);
 048        Buffer.BlockCopy(tag, 0, result, NonceSize + ciphertext.Length, TagSize);
 49
 050        return Convert.ToBase64String(result);
 051    }
 52
 53    private static void ValidateKey(byte[] key)
 54    {
 055        if (key.Length != 32)
 56        {
 057            throw new ArgumentException($"Key must be 256 bits (32 bytes). Got {key.Length} bytes.");
 58        }
 059    }
 60}