< Summary

Information
Class: MyNet.Utilities.Encryption.AesEncryptionService
Assembly: MyNet.Utilities
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Utilities/Encryption/AesEncryptionService.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 26
Uncovered lines: 0
Coverable lines: 26
Total lines: 110
Line coverage: 100%
Branch coverage
75%
Covered branches: 6
Total branches: 8
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Concat(...)100%44100%
SubArray(...)100%11100%
Encrypt(...)100%11100%
Encrypt(...)50%22100%
Decrypt(...)100%11100%
Decrypt(...)50%22100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Utilities/Encryption/AesEncryptionService.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="AesEncryptionService.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Security.Cryptography;
 9using System.Text;
 10
 11namespace MyNet.Utilities.Encryption;
 12
 13/// <summary>
 14/// Provides AES-GCM based encryption and decryption utilities using a pre-shared key.
 15/// </summary>
 16public class AesEncryptionService(byte[] key) : IEncryptionService
 17{
 18    private const int KeyBytes = 16;
 19    private const int NonceBytes = 12;
 20
 21    /// <summary>
 22    /// Concatenates two byte arrays into a single array.
 23    /// </summary>
 24    /// <param name="a">First byte array.</param>
 25    /// <param name="b">Second byte array.</param>
 26    /// <returns>The concatenated result of <paramref name="a"/> and <paramref name="b"/>.</returns>
 27    public static byte[] Concat(byte[] a, byte[] b)
 28    {
 1829        var output = new byte[a.Length + b.Length];
 30
 54031        for (var i = 0; i < a.Length; i++)
 32        {
 25233            output[i] = a[i];
 34        }
 35
 61236        for (var j = 0; j < b.Length; j++)
 37        {
 28838            output[a.Length + j] = b[j];
 39        }
 40
 1841        return output;
 42    }
 43
 44    /// <summary>
 45    /// Returns a sub-array extracted from the provided data.
 46    /// </summary>
 47    /// <param name="data">Source array.</param>
 48    /// <param name="start">Starting index.</param>
 49    /// <param name="length">Number of bytes to copy.</param>
 50    /// <returns>A new array containing the requested segment.</returns>
 51    public static byte[] SubArray(byte[] data, int start, int length)
 52    {
 2753        var result = new byte[length];
 54
 2755        Array.Copy(data, start, result, 0, length);
 56
 2757        return result;
 58    }
 59
 60    /// <summary>
 61    /// Encrypts the provided bytes using AES-GCM and returns a combined payload containing tag, nonce and ciphertext.
 62    /// </summary>
 63    /// <param name="toEncrypt">Plain bytes to encrypt.</param>
 64    /// <returns>Combined tag + nonce + ciphertext.</returns>
 65    public byte[] Encrypt(byte[] toEncrypt)
 66    {
 967        var tag = new byte[KeyBytes];
 968        var nonce = new byte[NonceBytes];
 969        var cipherText = new byte[toEncrypt.Length];
 70
 971        using var cipher = new AesGcm(key, KeyBytes);
 972        cipher.Encrypt(nonce, toEncrypt, cipherText, tag);
 73
 974        return Concat(tag, Concat(nonce, cipherText));
 975    }
 76
 77    /// <summary>
 78    /// Encrypts the provided string using UTF8 encoding and returns the result as a base64 string.
 79    /// </summary>
 80    /// <param name="text">The text to encrypt.</param>
 81    /// <returns>Base64-encoded encrypted payload.</returns>
 982    public string Encrypt(string? text) => Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(text ?? string.Empty)))
 83
 84    /// <summary>
 85    /// Decrypts the combined payload produced by <see cref="Encrypt(byte[])"/> and returns the plaintext bytes.
 86    /// </summary>
 87    /// <param name="cipherText">Combined tag + nonce + ciphertext produced by <see cref="Encrypt(byte[])"/>.</param>
 88    /// <returns>The decrypted plaintext bytes.</returns>
 89    public byte[] Decrypt(byte[] cipherText)
 90    {
 991        var tag = SubArray(cipherText, 0, KeyBytes);
 992        var nonce = SubArray(cipherText, KeyBytes, NonceBytes);
 93
 994        var toDecrypt = SubArray(cipherText, KeyBytes + NonceBytes, cipherText.Length - tag.Length - nonce.Length);
 995        var decryptedData = new byte[toDecrypt.Length];
 96
 997        using var cipher = new AesGcm(key, KeyBytes);
 998        cipher.Decrypt(nonce, toDecrypt, tag, decryptedData);
 99
 9100        return decryptedData;
 9101    }
 102
 103    /// <summary>
 104    /// Decrypts the provided base64-encoded payload and returns the decrypted UTF8 string.
 105    /// </summary>
 106    /// <param name="text">Base64-encoded payload to decrypt.</param>
 107    /// <returns>Decrypted UTF8 string.</returns>
 9108    public string Decrypt(string? text) => !string.IsNullOrEmpty(text) ? Encoding.UTF8.GetString(Decrypt(Convert.FromBas
 109}
 110