Lyo.Encryption
1.0.0
dotnet add package Lyo.Encryption --version 1.0.0
NuGet\Install-Package Lyo.Encryption -Version 1.0.0
<PackageReference Include="Lyo.Encryption" Version="1.0.0" />
<PackageVersion Include="Lyo.Encryption" Version="1.0.0" />
<PackageReference Include="Lyo.Encryption" />
paket add Lyo.Encryption --version 1.0.0
#r "nuget: Lyo.Encryption, 1.0.0"
#:package Lyo.Encryption@1.0.0
#addin nuget:?package=Lyo.Encryption&version=1.0.0
#tool nuget:?package=Lyo.Encryption&version=1.0.0
Lyo.Encryption
Production-oriented authenticated encryption for .NET: symmetric AEAD (AES-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305, AES-CCM, AES-SIV), RSA and AES-GCM + RSA hybrids, plus envelope / two-key flows via ITwoKeyEncryptionService.
Primary contracts: IEncryptionService (single key), ITwoKeyEncryptionService (per-operation DEK wrapped by a KEK), and EncryptionServiceBase (streaming, string, and file helpers). Keys can be inline or resolved from Lyo.KeyStore by keyId.
For architecture, threat model, and operational checklists, see the Security/Encryption README — this file covers this assembly’s API surface.
Features
Algorithms
Confidentiality + integrity (authenticated tags); tampering surfaces as DecryptionFailedException.
- Symmetric AEAD: AES-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305, AES-CCM, AES-SIV
- RSA encrypt/decrypt and AES-GCM + RSA hybrid
- Envelope / two-key via
ITwoKeyEncryptionService
Keying
- Inline
byte[] key/byte[] kek, orIKeyStorelookup bykeyId - Versioned decrypt / rotation on two-key paths
I/O
- Streaming —
EncryptToStreamAsync/DecryptToStreamAsyncfor large payloads (framed wire format) - Files —
EncryptToFileAsync,DecryptFromFileAsync, and stream-to-file variants - Strings —
EncryptString/DecryptStringwith per-direction encoding (UTF-8 by default)
Integration
- DI helpers for RSA / AES-GCM+RSA, keyed
ITwoKeyEncryptionService+IKeyStore - Algorithm discovery via
EncryptionAlgorithm/EncryptionAlgorithmDiscovery - Non-throwing
EncryptionResult/DecryptionResult(Lyo.Result) SecurityUtilitiesfor buffer zeroing and constant-time compare (not KDFs — seeLyo.KeyStore)
Examples
Keyed two-key (recommended)
using Lyo.Encryption;
using Lyo.Encryption.AesGcm;
using Lyo.Encryption.Extensions;
using Lyo.Encryption.TwoKey;
using Lyo.KeyStore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
const string keyName = "primary";
// Configure key store via lambda (read secrets from IConfiguration inside configure)
services.AddKeyedLocalKeyStore(keyName, store =>
{
store.UpdateKeyFromString("default-key", "replace-in-production");
});
// Or inline factory with IConfiguration (custom IKeyStore types)
services.AddEncryptionServiceKeyed<MyKeyStore>(
keyName,
sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var ks = new MyKeyStore(sp);
ks.UpdateKeyFromString("default-key", config["Encryption:KekSecret"]!);
return ks;
},
aesGcmKeySize: AesGcmKeySizeBits.Bits256);
// AES-GCM DEK + KEK (built into this package)
services.AddEncryptionServiceKeyed(keyName, keyStoreName: keyName);
// Mixed algorithms (examples)
services.AddEncryptionServiceKeyed<XChaCha20Poly1305EncryptionService, AesGcmEncryptionService>(keyName, keyName);
// Resolve
var envelope = serviceProvider.GetRequiredKeyedService<ITwoKeyEncryptionService>(keyName);
Unkeyed (single algorithm / cache helper)
services.AddLocalKeyStore(ks => ks.UpdateKeyFromString("k", "dev-secret"));
// Built-in types use core keyed helpers; addons:
// services.AddAesCcmEncryption(); // from Lyo.Encryption.AesCcm
services.AddDefaultEncryptionService<AesGcmEncryptionService>(); // after registering that concrete
RSA / hybrid
services.AddRsaEncryption(publicPemPath: "keys/public.pem", privatePemPath: "keys/private.pem");
services.AddAesGcmRsaEncryption(publicPemPath: "keys/public.pem", privatePemPath: "keys/private.pem");
Benchmarks
AES-GCM encrypts 10 MB in ~5 ms with gigabyte-class throughput.
- Portfolio suite:
encryption - AES-GCM encrypt
- Benchmark summary
Service matrix
| Type | Role |
|---|---|
AesGcmEncryptionService |
AES-GCM; key size via AesGcmKeySizeBits |
ChaCha20Poly1305EncryptionService |
ChaCha20-Poly1305 (IETF nonce) |
XChaCha20Poly1305EncryptionService |
XChaCha20-Poly1305 (extended nonce) |
AesCcmEncryptionService |
AES-CCM |
AesSivEncryptionService |
AES-SIV (misuse-resistant synthetic IV) |
RsaEncryptor / RsaDecryptor |
RSA encrypt (public key) / decrypt (private key), chunked for large plaintext |
AesGcmRsaEncryptionService |
Hybrid: RSA wraps AES key, AES-GCM protects payload |
TwoKeyEncryptionService<TKek, TDek> |
Envelope: random DEK per operation, KEK encrypts DEK |
Concrete types live under AesGcm/, ChaCha20Poly1305/, Symmetric/Aes/*, Symmetric/ChaCha/*, Rsa/, AesGcmRsa/, and TwoKey/.
IEncryptionService (single-key path)
Encrypt/Decryptonbyte[],ReadOnlySpan<byte>, or slice overloadsEncryptString/DecryptStringEncryptToStreamAsync/DecryptToStreamAsync— output begins with a small header (format version, algorithm id, reserved bytes) followed by length-prefixed encrypted chunks (default plaintext chunk size 1 MiB; configurable)EncryptToFileAsync/DecryptFromFileAsync
ITwoKeyEncryptionService (envelope)
EncryptreturnsTwoKeyEncryptionResult: ciphertext + encrypted DEK +KeyId/KeyVersion(+ optional salt metadata)Decrypttakes ciphertext and encrypted DEK separatelyEncryptStreamAsync/DecryptToStreamAsync— combined stream layout: encrypted DEK first, then chunked ciphertext (see XML onTwoKeyEncryptionServicefor format notes)ReEncryptDek/ReEncryptDekAsync— rotate or migrate KEK without re-encrypting bulk data
Thread safety
EncryptionServiceBase documents that multiple threads may call the same instance concurrently; each invocation uses its own cryptographic context. If IKeyStore (or other dependencies) are not thread-safe, synchronize or scope lifetimes accordingly.
Dependency injection (this assembly)
Register Microsoft.Extensions.DependencyInjection.Abstractions (already referenced by this package on netstandard2.0 and net10.0). Algorithm addons ( Lyo.Encryption.AesCcm, .AesSiv, .XChaCha20Poly1305) add their own Add*Encryption helpers; keys come from Lyo.KeyStore.
Registration overview
| Call | Registers |
|---|---|
AddLocalKeyStore(configure) |
LocalKeyStore + unkeyed IKeyStore |
AddKeyedLocalKeyStore(key, configure) |
Per-key LocalKeyStore + IKeyStore |
AddEncryptionServiceKeyed(...) |
Keyed DEK/KEK concretes, IEncryptionService, ITwoKeyEncryptionService |
AddAesCcmEncryption() (addon) |
Unkeyed AesCcmEncryptionService only |
AddDefaultEncryptionService<T>() |
Unkeyed IEncryptionService → T |
AddDefaultTwoKeyEncryptionService<T>() |
Unkeyed ITwoKeyEncryptionService → T (rare) |
AddRsaEncryption / AddAesGcmRsaEncryption |
Scoped RSA / hybrid services (paths or PFX) |
Unkeyed addon methods do not register IEncryptionService until you call AddDefaultEncryptionService<TConcrete>(). File storage and envelope encryption should use keyed registration (includes ITwoKeyEncryptionService).
Keyed two-key (recommended)
AddEncryptionServiceKeyed overloads accept an existing keyed key-store name, or register the store via Func<IServiceProvider, TKeyStore>. Generic overloads support different DEK vs KEK types when both implement IEncryptionService and are built from IKeyStore (see source for the built-in type matrix).
Configuration notes
- Service options (
EncryptionServiceOptions:MaxInputSize,FileExtension,AesGcmKeySize, etc.) are set on concrete service constructors today — use algorithm parameters onAddEncryptionServiceKeyed(aesGcmKeySize) or construct services manually for advanced cases. - Secrets and key material — use
AddLocalKeyStore/AddKeyedLocalKeyStorewithconfigure => { ... }and readIConfigurationinside that callback (same pattern as other Lyo apps). There is noAddEncryptionServiceFromConfigurationon this package; bind appsettings in the key-store configure delegate or in a customIKeyStorefactory.
Options
EncryptionServiceOptions (per concrete service):
| Property | Typical use |
|---|---|
FileExtension |
Suffix for encrypted artifacts (required non-empty on base ctor) |
MinInputSize / MaxInputSize |
Enforced on encrypt paths |
CurrentFormatVersion |
Stream/header version; defaults align with StreamFormatVersion.V1 |
AesGcmKeySize / AesSivKeySize |
Algorithm-specific key material where applicable |
Result and error types
Lyo.Encryption.Models.EncryptionResult/DecryptionResult–Result<byte[]>with key metadata for APIs that avoid exceptionsLyo.Encryption.EncryptionErrorCodes– stable error-code constants paired withEncryptionResult/DecryptionResult(for exampleKEY_NOT_FOUND,DECRYPTION_FAILED,INVALID_HEADER); use these instead of string-matching exception messagesDecryptionFailedException,EncryptionException,InvalidDataException,ArgumentOutsideRangeException– seeIEncryptionServiceXML for which throws apply
Helpers and validation
Lyo.Encryption.TwoKey.TwoKeyDekValidation– validatesDekAlgorithm+ DEK key-material byte length for all supported symmetric algorithms; used on decrypt to reject mismatched envelopes before any cryptographic call.Lyo.Encryption.RsaKeyLoader– PEM/PFX RSA key loading helper. Uses BouncyCastle onnetstandard2.0andRSA.ImportFromPem/X509Certificate2onnet10.0. Invoked transitively byRsaEncryptor/RsaDecryptor/AesGcmRsaEncryptionServiceconstructors but exposed for callers that want to share a loaded key across services.Lyo.Encryption.ISymmetricKeyMaterialSize– implemented by every symmetricIEncryptionServiceto advertise its accepted key-material sizes in bytes (e.g. AES-GCM ={16, 24, 32}, XChaCha20-Poly1305 ={32}).TwoKeyDekValidationand key-store validators rely on this.Encrypt/DecryptReadOnlySpan<byte>overloads onIEncryptionService— zero-copy entry points for callers that already hold a contiguous buffer; the legacybyte[]overloads remain.TwoKeyEncryptionResultfields — beyond the obvious ciphertext, the record carriesEncryptedDek,DekKeyMaterialBytes,KeyEncryptionKeySalt,KeyId,KeyVersion, andTotalSize. The legacyLyo.Encryption.Models.TwoKeyEncryptionResultis preserved for callers that still consume the result-builder shape.
Helpers and validation — Streaming two-key
EncryptStreamAsync(Stream input, Stream output, ...)/DecryptStreamAsync(Stream input, Stream output, TwoKeyEncryptionResult metadata, ...)— operates on an existingTwoKeyEncryptionResult(carries the wrapped DEK, key id/version, salt).EncryptToStreamAsync(...)/DecryptToStreamAsync(...)— writes the combined wire format (encrypted-DEK header + chunked ciphertext) to a single output stream and reads it back without external metadata.
Upgrade checklist (short)
- Confirm nonce / IV uniqueness policy for each algorithm when integrating custom stores (see parent
README.md). - After dependency bumps (BouncyCastle, Dorssel AES extras), run
Lyo.Encryption.Benchmarksin Release with algorithm-specific filters. - Validate FIPS / regional requirements externally — this library follows general best practices but does not certify every jurisdiction.
Dependencies
Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).
Lyo.Common— (direct, lyo)Lyo.Exceptions— (direct, lyo)Lyo.Hashing— (direct, lyo)Lyo.KeyStore— (direct, lyo)Lyo.Result— (direct, lyo)Lyo.Streams— (direct, lyo)BouncyCastle.Cryptography2.6.2— (direct, third-party, netstandard2.0)Microsoft.Bcl.AsyncInterfaces10.0.5— (direct, microsoft, netstandard2.0)Microsoft.Extensions.DependencyInjection.Abstractions10.0.5— (direct, microsoft, net10.0, netstandard2.0)System.Threading.Tasks.Extensions4.6.3— (direct, microsoft, netstandard2.0)Konscious.Security.Cryptography.Argon21.3.1— (transitive, third-party)Microsoft.Extensions.Logging.Abstractions10.0.5— (transitive, microsoft)System.Buffers4.6.1— (transitive, microsoft, netstandard2.0)System.IO.Hashing10.0.5— (transitive, microsoft, net10.0)System.Memory4.6.3— (transitive, microsoft, netstandard2.0)System.Text.Json10.0.5— (transitive, microsoft, netstandard2.0)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- BouncyCastle.Cryptography (>= 2.6.2)
- Lyo.Common (>= 1.0.0)
- Lyo.Exceptions (>= 1.0.0)
- Lyo.Hashing (>= 1.0.0)
- Lyo.KeyStore (>= 1.0.0)
- Lyo.Result (>= 1.0.0)
- Lyo.Streams (>= 1.0.0)
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.5)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- System.Threading.Tasks.Extensions (>= 4.6.3)
-
net10.0
- Lyo.Common (>= 1.0.0)
- Lyo.Exceptions (>= 1.0.0)
- Lyo.Hashing (>= 1.0.0)
- Lyo.KeyStore (>= 1.0.0)
- Lyo.Result (>= 1.0.0)
- Lyo.Streams (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
NuGet packages (14)
Showing the top 5 NuGet packages that depend on Lyo.Encryption:
| Package | Downloads |
|---|---|
|
Lyo.Web.Components
Blazor components library for the Lyo web UI framework with MudBlazor integration. |
|
|
Lyo.Cache
Cache service abstractions and local IMemoryCache implementation. |
|
|
Lyo.FileMetadataStore
File store service interface and base implementation for metadata and file tracking. |
|
|
Lyo.FileStorage
File storage service interface and base implementation for file operations. |
|
|
Lyo.KeyStore.Aws
AWS Secrets Manager implementation of the Lyo KeyStore interface for production key management. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 165 | 8/16/2026 |