From d5a41a8389d8ba48203867eadc4982cb77d818e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Vetni=C4=87?= Date: Wed, 7 Feb 2024 09:54:49 +0100 Subject: [PATCH] feat: add libsodium decrypter (wip) --- BuildingBlocks/src/Crypto/Crypto.csproj | 7 +- .../LibsodiumSymmetricEncrypter.cs | 65 ++++++++ .../src/Messages.Domain/Entities/Message.cs | 9 +- .../Messages.Application.Tests.csproj | 2 + .../Tests/AutoMapper/DecryptTest.cs | 140 ++++++++++++++++++ 5 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 BuildingBlocks/src/Crypto/Implementations/LibsodiumSymmetricEncrypter.cs create mode 100644 Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/DecryptTest.cs diff --git a/BuildingBlocks/src/Crypto/Crypto.csproj b/BuildingBlocks/src/Crypto/Crypto.csproj index c9d87fc2db..7391beceb2 100644 --- a/BuildingBlocks/src/Crypto/Crypto.csproj +++ b/BuildingBlocks/src/Crypto/Crypto.csproj @@ -1,4 +1,4 @@ - + enable @@ -20,6 +20,11 @@ + + + + + diff --git a/BuildingBlocks/src/Crypto/Implementations/LibsodiumSymmetricEncrypter.cs b/BuildingBlocks/src/Crypto/Implementations/LibsodiumSymmetricEncrypter.cs new file mode 100644 index 0000000000..62609a7942 --- /dev/null +++ b/BuildingBlocks/src/Crypto/Implementations/LibsodiumSymmetricEncrypter.cs @@ -0,0 +1,65 @@ +using System.Text; +using System.Text.Json; +using Backbone.Tooling.JsonConverters; +using Sodium; + +// ReSharper disable InconsistentNaming +#pragma warning disable IDE1006 + +namespace Backbone.Crypto.Implementations; +public class LibsodiumSymmetricEncrypter +{ + public static byte[] DecryptXChaCha20Poly1305(byte[] body, string serializedSecret) + { + var bodyString = Encoding.UTF8.GetString(body); + var deserializedBody = JsonSerializer.Deserialize(bodyString, + new JsonSerializerOptions { Converters = { new UrlSafeBase64ToByteArrayJsonConverter() } }) ?? + throw new InvalidOperationException("Decryption failed."); + + var cipherText = deserializedBody.cph.Replace('-', '+').Replace('_', '/') + "="; + var payload = Convert.FromBase64String(cipherText); + + var nonce = Convert.FromBase64String(deserializedBody.nnc); + + var deserializedSecret = JsonSerializer.Deserialize(serializedSecret, + new JsonSerializerOptions { Converters = { new UrlSafeBase64ToByteArrayJsonConverter() } }); + var key = Convert.FromBase64String(deserializedSecret!.key + "="); + + return DecryptXChaCha20Poly1305(payload, nonce, key); + } + + public static byte[] DecryptXChaCha20Poly1305(byte[] payload, byte[] nonce, byte[] key) + { + if (nonce.Length != 24) + throw new ArgumentException("Nonce must be 24 bytes long for XChaCha20-Poly1305.", nameof(nonce)); + if (key.Length != 32) + throw new ArgumentException("Key must be 32 bytes long for XChaCha20-Poly1305.", nameof(key)); + + try + { + var decryptedData = SecretAeadXChaCha20Poly1305.Decrypt(payload, nonce, key); + return decryptedData; + } + catch (Exception ex) + { + throw new InvalidOperationException("Decryption failed.", ex); + } + } + + private class CryptoCipher + { + /** + * Algorithm (`alg`) and `@Type` fields are omitted due to not being used in the code. + */ + public required string cph { get; init; } + public required string nnc { get; init; } + } + + private class Secret + { + /** + * Algorithm (`alg`) field is omitted due to not being used in the code. + */ + public required string key { get; init; } + } +} diff --git a/Modules/Messages/src/Messages.Domain/Entities/Message.cs b/Modules/Messages/src/Messages.Domain/Entities/Message.cs index c547500fee..c94bb02f76 100644 --- a/Modules/Messages/src/Messages.Domain/Entities/Message.cs +++ b/Modules/Messages/src/Messages.Domain/Entities/Message.cs @@ -1,5 +1,4 @@ -using Backbone.Crypto; -using Backbone.Crypto.Implementations.Deprecated.BouncyCastle.Symmetric; +using Backbone.Crypto.Implementations; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Messages.Domain.Ids; using Backbone.Tooling; @@ -46,6 +45,7 @@ public void LoadBody(byte[] bytes) Body = bytes; } +<<<<<<< Updated upstream public string DecryptBody(string symmetricKey) { return BitConverter.ToString(Body); @@ -55,5 +55,10 @@ public ConvertibleString DecryptBodyWithSymmetricKey(ConvertibleString encrypted { var aesEncryptionHelper = AesSymmetricEncrypter.CreateWith96BitIv128BitMac(); return aesEncryptionHelper.Decrypt(encrypted, symmetricKey); +======= + public string DecryptBody(string secretKey) + { + return Encoding.UTF8.GetString(LibsodiumSymmetricEncrypter.DecryptXChaCha20Poly1305(Body, secretKey)); +>>>>>>> Stashed changes } } diff --git a/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj b/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj index ed8c83073e..fe4965498d 100644 --- a/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj +++ b/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj @@ -16,6 +16,8 @@ + + diff --git a/Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/DecryptTest.cs b/Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/DecryptTest.cs new file mode 100644 index 0000000000..6456c3616f --- /dev/null +++ b/Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/DecryptTest.cs @@ -0,0 +1,140 @@ +using Sodium; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Xunit; +using Backbone.Tooling.JsonConverters; +using System.Text.Json; +using Backbone.Crypto.Implementations; +using Backbone.Modules.Messages.Domain.Entities; +using Backbone.UnitTestTools.Data; + +namespace Backbone.Modules.Messages.Application.Tests.Tests.AutoMapper; +public class DecryptTest +{ + [Fact] + public void DecryptTest_Test() + { + var secret = new byte[] { 201, 46, 175, 20, 46, 244, 122, 153, 152, 22, 133, 0, 34, 138, 101, 184, 185, 137, 37, 65, 249, 240, 85, 70, 159, 2, 55, 1, 29, 95, 61, 159 }; + var nonce = new byte[] { 94, 51, 92, 74, 14, 221, 224, 69, 110, 177, 185, 235, 61, 52, 57, 218, 59, 149, 120, 29, 112, 40, 245, 9 }; + var bodyTest = new byte[] + { + 155, 199, 40, 26, 102, 100, 69, 125, 57, 64, 201, 18, 176, 32, 87, 172, 182, 196, 192, 71, 226, 84, 148, 45, 19, 155, 181, 213, 233, 21, 46, 230, 54, 224, 191, 42, 223, 12, 50, 75, 251, + 60, 78, 236, 166, 56, 227, 7, 140, 86, 183, 70, 65, 20, 31, 98, 229, 66, 149, 226, 222, 47, 86, 241, 139, 145, 44, 247, 111, 37, 150, 238, 140, 62, 198, 170, 236, 32, 38, 73, 218, 148, 3, + 44, 215, 138, 155, 250, 103, 88, 231, 93, 58, 150, 113, 16, 112, 157, 163, 208, 71, 98, 69, 150, 207, 71, 56, 200, 113, 112, 82, 230, 252, 26, 242, 93, 210, 173, 219, 126, 91, 135, 209, + 209, 4, 165, 101, 135, 107, 88, 104, 3, 240, 134, 5, 118, 74, 231, 50, 21, 92, 227, 131, 202, 163, 223, 157, 93, 15, 60, 191, 34, 24, 142, 115, 62, 124, 142, 105, 250, 239, 208, 33, 21, + 128, 117, 248, 205, 23, 149, 156, 219, 214, 1, 143, 142, 97, 15, 120, 52, 2, 68, 96, 103, 203, 145, 239, 251, 229, 149, 117, 225, 243, 180, 169, 49, 187, 0, 197, 42, 153, 101, 175, 163, + 13, 144, 26, 83, 24, 202, 128, 49, 87, 109, 42, 48, 172, 20, 167, 175, 73, 161, 209, 72, 100, 115, 0, 160, 96, 197, 166, 218, 118, 104, 23, 81, 250, 93, 128, 65, 31, 189, 138, 235, 223, + 230, 36, 207, 248, 55, 86, 245, 164, 0, 114, 12, 23, 245, 178, 165, 115, 193, 141, 240, 123, 216, 206, 16, 215, 52, 244, 227, 147, 38, 123, 103, 228, 23, 169, 244, 220, 15, 154, 246, 92, + 242, 177, 133, 132, 167, 241, 50, 177, 244, 139, 23, 118, 9, 28, 54, 98, 169, 156, 17, 146, 224, 51, 12, 165, 80, 5, 234, 9, 3, 196, 20, 137, 125, 82, 239, 19, 224, 232, 73, 187, 0, 49, + 243, 71, 178, 234, 91, 162, 187, 94, 235, 248, 45, 139, 194, 218, 246, 224, 65, 170, 140, 245, 26, 126, 230, 54, 79, 16, 19, 249, 152, 228, 234, 15, 211, 134, 23, 93, 60, 251, 94, 151, + 168, 98, 217, 232, 200, 140, 206, 113, 251, 41, 97, 70, 230, 12, 105, 220, 87, 137, 58, 117, 161, 183, 3, 206, 10, 185, 21, 137, 49, 151, 19, 209, 129, 240, 188, 88, 19, 159, 232, 35, 232, + 108, 63, 228, 1, 140, 67, 59, 204, 81, 239, 39, 86, 4, 158, 23, 11, 46, 138, 216, 161, 45, 56, 218, 52, 235, 162, 209, 130, 150, 229, 137, 80, 33, 103, 123, 108, 245, 252 + }; + var bodyDb = new byte[] { + 123, 34, 99, 112, 104, 34, 58, 34, 109, 56, 99, 111, 71, 109, 90, 107, 82, 88, 48, 53, 81, 77, 107, 83, 115, 67, 66, 88, 114, 76, 98, 69, 119, 69, 102, 105, 86, 74, 81, 116, 69, 53, 117, + 49, 49, 101, 107, 86, 76, 117, 89, 50, 52, 76, 56, 113, 51, 119, 119, 121, 83, 95, 115, 56, 84, 117, 121, 109, 79, 79, 77, 72, 106, 70, 97, 51, 82, 107, 69, 85, 72, 50, 76, 108, 81, 112, + 88, 105, 51, 105, 57, 87, 56, 89, 117, 82, 76, 80, 100, 118, 74, 90, 98, 117, 106, 68, 55, 71, 113, 117, 119, 103, 74, 107, 110, 97, 108, 65, 77, 115, 49, 52, 113, 98, 45, 109, 100, 89, + 53, 49, 48, 54, 108, 110, 69, 81, 99, 74, 50, 106, 48, 69, 100, 105, 82, 90, 98, 80, 82, 122, 106, 73, 99, 88, 66, 83, 53, 118, 119, 97, 56, 108, 51, 83, 114, 100, 116, 45, 87, 52, 102, + 82, 48, 81, 83, 108, 90, 89, 100, 114, 87, 71, 103, 68, 56, 73, 89, 70, 100, 107, 114, 110, 77, 104, 86, 99, 52, 52, 80, 75, 111, 57, 45, 100, 88, 81, 56, 56, 118, 121, 73, 89, 106, 110, + 77, 45, 102, 73, 53, 112, 45, 117, 95, 81, 73, 82, 87, 65, 100, 102, 106, 78, 70, 53, 87, 99, 50, 57, 89, 66, 106, 52, 53, 104, 68, 51, 103, 48, 65, 107, 82, 103, 90, 56, 117, 82, 55, 95, + 118, 108, 108, 88, 88, 104, 56, 55, 83, 112, 77, 98, 115, 65, 120, 83, 113, 90, 90, 97, 45, 106, 68, 90, 65, 97, 85, 120, 106, 75, 103, 68, 70, 88, 98, 83, 111, 119, 114, 66, 83, 110, 114, + 48, 109, 104, 48, 85, 104, 107, 99, 119, 67, 103, 89, 77, 87, 109, 50, 110, 90, 111, 70, 49, 72, 54, 88, 89, 66, 66, 72, 55, 50, 75, 54, 57, 95, 109, 74, 77, 95, 52, 78, 49, 98, 49, 112, + 65, 66, 121, 68, 66, 102, 49, 115, 113, 86, 122, 119, 89, 51, 119, 101, 57, 106, 79, 69, 78, 99, 48, 57, 79, 79, 84, 74, 110, 116, 110, 53, 66, 101, 112, 57, 78, 119, 80, 109, 118, 90, 99, + 56, 114, 71, 70, 104, 75, 102, 120, 77, 114, 72, 48, 105, 120, 100, 50, 67, 82, 119, 50, 89, 113, 109, 99, 69, 90, 76, 103, 77, 119, 121, 108, 85, 65, 88, 113, 67, 81, 80, 69, 70, 73, 108, + 57, 85, 117, 56, 84, 52, 79, 104, 74, 117, 119, 65, 120, 56, 48, 101, 121, 54, 108, 117, 105, 117, 49, 55, 114, 45, 67, 50, 76, 119, 116, 114, 50, 52, 69, 71, 113, 106, 80, 85, 97, 102, + 117, 89, 50, 84, 120, 65, 84, 45, 90, 106, 107, 54, 103, 95, 84, 104, 104, 100, 100, 80, 80, 116, 101, 108, 54, 104, 105, 50, 101, 106, 73, 106, 77, 53, 120, 45, 121, 108, 104, 82, 117, + 89, 77, 97, 100, 120, 88, 105, 84, 112, 49, 111, 98, 99, 68, 122, 103, 113, 53, 70, 89, 107, 120, 108, 120, 80, 82, 103, 102, 67, 56, 87, 66, 79, 102, 54, 67, 80, 111, 98, 68, 95, 107, 65, + 89, 120, 68, 79, 56, 120, 82, 55, 121, 100, 87, 66, 74, 52, 88, 67, 121, 54, 75, 50, 75, 69, 116, 79, 78, 111, 48, 54, 54, 76, 82, 103, 112, 98, 108, 105, 86, 65, 104, 90, 51, 116, 115, + 57, 102, 119, 34, 44, 34, 97, 108, 103, 34, 58, 51, 44, 34, 110, 110, 99, 34, 58, 34, 88, 106, 78, 99, 83, 103, 55, 100, 52, 69, 86, 117, 115, 98, 110, 114, 80, 84, 81, 53, 50, 106, 117, + 86, 101, 66, 49, 119, 75, 80, 85, 74, 34, 44, 34, 64, 116, 121, 112, 101, 34, 58, 34, 67, 114, 121, 112, 116, 111, 67, 105, 112, 104, 101, 114, 34, 125 + }; + + var bodyTestString = System.Text.Encoding.UTF8.GetString(bodyTest); + var bodyDbString = System.Text.Encoding.UTF8.GetString(bodyDb); + + var bodyDbPayload = System.Convert.FromBase64String("m8coGmZkRX05QMkSsCBXrLbEwEfiVJQtE5u11ekVLuY24L8q3wwyS/s8TuymOOMHjFa3RkEUH2LlQpXi3i9W8YuRLPdvJZbujD7GquwgJknalAMs14qb+mdY5106lnEQcJ2j0EdiRZbPRzjIcXBS5vwa8l3Srdt+W4fR0QSlZYdrWGgD8IYFdkrnMhVc44PKo9+dXQ88vyIYjnM+fI5p+u/QIRWAdfjNF5Wc29YBj45hD3g0AkRgZ8uR7/vllXXh87SpMbsAxSqZZa+jDZAaUxjKgDFXbSowrBSnr0mh0UhkcwCgYMWm2nZoF1H6XYBBH72K69/mJM/4N1b1pAByDBf1sqVzwY3we9jOENc09OOTJntn5Bep9NwPmvZc8rGFhKfxMrH0ixd2CRw2YqmcEZLgMwylUAXqCQPEFIl9Uu8T4OhJuwAx80ey6luiu17r+C2Lwtr24EGqjPUafuY2TxAT+Zjk6g/ThhddPPtel6hi2ejIjM5x+ylhRuYMadxXiTp1obcDzgq5FYkxlxPRgfC8WBOf6CPobD/kAYxDO8xR7ydWBJ4XCy6K2KEtONo066LRgpbliVAhZ3ts9fw="); + + var cryptoCipher = JsonSerializer.Deserialize(bodyDbString, + new JsonSerializerOptions { Converters = { new UrlSafeBase64ToByteArrayJsonConverter() } }); + + var resString = cryptoCipher.cph; + resString = resString.Replace('-', '+'); + resString = resString.Replace('_', '/'); + resString += '='; + + var deserializedSecret = JsonSerializer.Deserialize("{\"key\":\"yS6vFC70epmYFoUAIopluLmJJUH58FVGnwI3AR1fPZ8\",\"alg\":3}", + new JsonSerializerOptions { Converters = { new UrlSafeBase64ToByteArrayJsonConverter() } }); + var key = deserializedSecret.key; + + + + //var bodyOfMessage = bodyDb; + //var bodyOfMessageAsString = Encoding.UTF8.GetString(bodyDb); + //var deserializedBodyOfMessage = JsonSerializer.Deserialize(bodyOfMessageAsString, + // new JsonSerializerOptions { Converters = { new UrlSafeBase64ToByteArrayJsonConverter() } }); + + //var bodyToDecrypt = Convert.FromBase64String(deserializedBodyOfMessage.cph); + //var nonceToDecryptWith = Convert.FromBase64String(deserializedBodyOfMessage.nnc); + + var res0 = LibsodiumSymmetricEncrypter.DecryptXChaCha20Poly1305(bodyTest, nonce, secret); + var res1 = LibsodiumSymmetricEncrypter.DecryptXChaCha20Poly1305(Convert.FromBase64String(resString), nonce, secret); + var res2 = LibsodiumSymmetricEncrypter.DecryptXChaCha20Poly1305(bodyDb, "{\"key\":\"yS6vFC70epmYFoUAIopluLmJJUH58FVGnwI3AR1fPZ8\",\"alg\":3}"); + + 1.Should().Be(1); + res0.Should().BeEquivalentTo(res2); + } + + [Fact] + public void Clean_test() + { + // Arrange + var body = new byte[] { + 123, 34, 99, 112, 104, 34, 58, 34, 109, 56, 99, 111, 71, 109, 90, 107, 82, 88, 48, 53, 81, 77, 107, 83, 115, 67, 66, 88, 114, 76, 98, 69, 119, 69, 102, 105, 86, 74, 81, 116, 69, 53, 117, + 49, 49, 101, 107, 86, 76, 117, 89, 50, 52, 76, 56, 113, 51, 119, 119, 121, 83, 95, 115, 56, 84, 117, 121, 109, 79, 79, 77, 72, 106, 70, 97, 51, 82, 107, 69, 85, 72, 50, 76, 108, 81, 112, + 88, 105, 51, 105, 57, 87, 56, 89, 117, 82, 76, 80, 100, 118, 74, 90, 98, 117, 106, 68, 55, 71, 113, 117, 119, 103, 74, 107, 110, 97, 108, 65, 77, 115, 49, 52, 113, 98, 45, 109, 100, 89, + 53, 49, 48, 54, 108, 110, 69, 81, 99, 74, 50, 106, 48, 69, 100, 105, 82, 90, 98, 80, 82, 122, 106, 73, 99, 88, 66, 83, 53, 118, 119, 97, 56, 108, 51, 83, 114, 100, 116, 45, 87, 52, 102, + 82, 48, 81, 83, 108, 90, 89, 100, 114, 87, 71, 103, 68, 56, 73, 89, 70, 100, 107, 114, 110, 77, 104, 86, 99, 52, 52, 80, 75, 111, 57, 45, 100, 88, 81, 56, 56, 118, 121, 73, 89, 106, 110, + 77, 45, 102, 73, 53, 112, 45, 117, 95, 81, 73, 82, 87, 65, 100, 102, 106, 78, 70, 53, 87, 99, 50, 57, 89, 66, 106, 52, 53, 104, 68, 51, 103, 48, 65, 107, 82, 103, 90, 56, 117, 82, 55, 95, + 118, 108, 108, 88, 88, 104, 56, 55, 83, 112, 77, 98, 115, 65, 120, 83, 113, 90, 90, 97, 45, 106, 68, 90, 65, 97, 85, 120, 106, 75, 103, 68, 70, 88, 98, 83, 111, 119, 114, 66, 83, 110, 114, + 48, 109, 104, 48, 85, 104, 107, 99, 119, 67, 103, 89, 77, 87, 109, 50, 110, 90, 111, 70, 49, 72, 54, 88, 89, 66, 66, 72, 55, 50, 75, 54, 57, 95, 109, 74, 77, 95, 52, 78, 49, 98, 49, 112, + 65, 66, 121, 68, 66, 102, 49, 115, 113, 86, 122, 119, 89, 51, 119, 101, 57, 106, 79, 69, 78, 99, 48, 57, 79, 79, 84, 74, 110, 116, 110, 53, 66, 101, 112, 57, 78, 119, 80, 109, 118, 90, 99, + 56, 114, 71, 70, 104, 75, 102, 120, 77, 114, 72, 48, 105, 120, 100, 50, 67, 82, 119, 50, 89, 113, 109, 99, 69, 90, 76, 103, 77, 119, 121, 108, 85, 65, 88, 113, 67, 81, 80, 69, 70, 73, 108, + 57, 85, 117, 56, 84, 52, 79, 104, 74, 117, 119, 65, 120, 56, 48, 101, 121, 54, 108, 117, 105, 117, 49, 55, 114, 45, 67, 50, 76, 119, 116, 114, 50, 52, 69, 71, 113, 106, 80, 85, 97, 102, + 117, 89, 50, 84, 120, 65, 84, 45, 90, 106, 107, 54, 103, 95, 84, 104, 104, 100, 100, 80, 80, 116, 101, 108, 54, 104, 105, 50, 101, 106, 73, 106, 77, 53, 120, 45, 121, 108, 104, 82, 117, + 89, 77, 97, 100, 120, 88, 105, 84, 112, 49, 111, 98, 99, 68, 122, 103, 113, 53, 70, 89, 107, 120, 108, 120, 80, 82, 103, 102, 67, 56, 87, 66, 79, 102, 54, 67, 80, 111, 98, 68, 95, 107, 65, + 89, 120, 68, 79, 56, 120, 82, 55, 121, 100, 87, 66, 74, 52, 88, 67, 121, 54, 75, 50, 75, 69, 116, 79, 78, 111, 48, 54, 54, 76, 82, 103, 112, 98, 108, 105, 86, 65, 104, 90, 51, 116, 115, + 57, 102, 119, 34, 44, 34, 97, 108, 103, 34, 58, 51, 44, 34, 110, 110, 99, 34, 58, 34, 88, 106, 78, 99, 83, 103, 55, 100, 52, 69, 86, 117, 115, 98, 110, 114, 80, 84, 81, 53, 50, 106, 117, + 86, 101, 66, 49, 119, 75, 80, 85, 74, 34, 44, 34, 64, 116, 121, 112, 101, 34, 58, 34, 67, 114, 121, 112, 116, 111, 67, 105, 112, 104, 101, 114, 34, 125 + }; + var secretKey = "{\"key\":\"yS6vFC70epmYFoUAIopluLmJJUH58FVGnwI3AR1fPZ8\",\"alg\":3}"; + + var identityAddress = TestDataGenerator.CreateRandomIdentityAddress(); + var deviceId = TestDataGenerator.CreateRandomDeviceId(); + + var message = new Message(identityAddress, deviceId, null, body, new List(), new List()); + var expectedBody = + "{\"@type\":\"MessageSigned\",\"message\":\"{\\\"@type\\\":\\\"MessageContentWrapper\\\",\\\"attachments\\\":[],\\\"content\\\":{\\\"content\\\":\\\"TestContent\\\"},\\\"createdAt\\\":\\\"2024-02-06T22:18:39.470Z\\\",\\\"recipients\\\":[\\\"id19khDhsE7Ak18BgMHEba7iczUdcg4Zjmew\\\"]}\",\"signatures\":[{\"recipient\":\"id19khDhsE7Ak18BgMHEba7iczUdcg4Zjmew\",\"signature\":\"{\\\"sig\\\":\\\"S8wFVW_NHwmydRIpDGgjbnm5YXICimfjBaupZO7T3firEIuu_NWogZwcgXMzC5YehXyERasueSVOrkGR0PnaDg\\\",\\\"alg\\\":1}\"}]}"; + + // Act + var decryptedBody = message.DecryptBody(secretKey); + + // Assert + decryptedBody.Should().BeEquivalentTo(expectedBody); + } + + public class CryptoCipher + { + public string cph { get; set; } + public int alg { get; set; } + public string nnc { get; set; } + } + + private class Secret + { + public string key { get; set; } + } +}