< Summary

Information
Class: Elsa.Secrets.Services.DefaultSecretValueProtector
Assembly: Elsa.Secrets
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Secrets/Services/DefaultSecretValueProtector.cs
Line coverage
100%
Covered lines: 26
Uncovered lines: 0
Coverable lines: 26
Total lines: 52
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Protect(...)100%11100%
Unprotect(...)100%44100%
GetKey()100%1212100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Secrets/Services/DefaultSecretValueProtector.cs

#LineLine coverage
 1using System.Security.Cryptography;
 2using Microsoft.Extensions.Options;
 3
 4namespace Elsa.Secrets.Services;
 5
 396public class DefaultSecretValueProtector(IOptions<SecretsOptions> options) : ISecretValueProtector
 7{
 8    private const int NonceSize = 12;
 9    private const int TagSize = 16;
 10
 11    public string Protect(string value)
 12    {
 3113        var nonce = RandomNumberGenerator.GetBytes(NonceSize);
 3114        var plaintext = System.Text.Encoding.UTF8.GetBytes(value);
 3115        var ciphertext = new byte[plaintext.Length];
 3116        var tag = new byte[TagSize];
 17
 3118        using var aes = new AesGcm(GetKey(), TagSize);
 2719        aes.Encrypt(nonce, plaintext, ciphertext, tag);
 20
 2721        return string.Join(".", "v1", Convert.ToBase64String(nonce), Convert.ToBase64String(tag), Convert.ToBase64String
 2722    }
 23
 24    public string Unprotect(string protectedValue)
 25    {
 726        var parts = protectedValue.Split('.');
 727        if (parts.Length != 4 || parts[0] != "v1")
 328            throw new InvalidOperationException("The protected secret payload is not supported.");
 29
 430        var nonce = Convert.FromBase64String(parts[1]);
 331        var tag = Convert.FromBase64String(parts[2]);
 332        var ciphertext = Convert.FromBase64String(parts[3]);
 333        var plaintext = new byte[ciphertext.Length];
 34
 335        using var aes = new AesGcm(GetKey(), TagSize);
 336        aes.Decrypt(nonce, ciphertext, tag, plaintext);
 37
 338        return System.Text.Encoding.UTF8.GetString(plaintext);
 339    }
 40
 41    private byte[] GetKey()
 42    {
 3443        var key = options.Value.EncryptionKey;
 3444        if (key == null || key.Length == 0)
 245            throw new InvalidOperationException("Elsa Secrets encryption key is not configured. Configure SecretsOptions
 46
 3247        if (key.Length is not (16 or 24 or 32))
 248            throw new InvalidOperationException("Elsa Secrets encryption key must be exactly 16, 24, or 32 bytes.");
 49
 3050        return key;
 51    }
 52}