Lyo.Encryption
1.0.6
dotnet add package Lyo.Encryption --version 1.0.6
NuGet\Install-Package Lyo.Encryption -Version 1.0.6
<PackageReference Include="Lyo.Encryption" Version="1.0.6" />
<PackageVersion Include="Lyo.Encryption" Version="1.0.6" />
<PackageReference Include="Lyo.Encryption" />
paket add Lyo.Encryption --version 1.0.6
#r "nuget: Lyo.Encryption, 1.0.6"
#:package Lyo.Encryption@1.0.6
#addin nuget:?package=Lyo.Encryption&version=1.0.6
#tool nuget:?package=Lyo.Encryption&version=1.0.6
Lyo.Encryption
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 types and methods.
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, which 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, and others) 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, the 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 exceptions.Lyo.Encryption.EncryptionErrorCodes.Stable error-code constants paired withEncryptionResult/DecryptionResult, for exampleKEY_NOT_FOUND,DECRYPTION_FAILED,INVALID_HEADER. Use these instead of string-matching exception messages.DecryptionFailedException,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 ciphertext, the record carriesEncryptedDek,DekKeyMaterialBytes,KeyEncryptionKeySalt,KeyId,KeyVersion, andTotalSize. The legacyLyo.Encryption.Models.TwoKeyEncryptionResultis preserved for callers that still consume the result-builder shape.
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.6)
- Lyo.Exceptions (>= 1.0.6)
- Lyo.Hashing (>= 1.0.6)
- Lyo.KeyStore (>= 1.0.6)
- Lyo.Result (>= 1.0.6)
- Lyo.Streams (>= 1.0.6)
- 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.6)
- Lyo.Exceptions (>= 1.0.6)
- Lyo.Hashing (>= 1.0.6)
- Lyo.KeyStore (>= 1.0.6)
- Lyo.Result (>= 1.0.6)
- Lyo.Streams (>= 1.0.6)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
NuGet packages (14)
Showing the top 5 NuGet packages that depend on Lyo.Encryption:
| Package | Downloads |
|---|---|
|
Lyo.Cache
Cache service abstractions and local IMemoryCache implementation. |
|
|
Lyo.Web.Components
Blazor components library for the Lyo web UI framework with MudBlazor integration. |
|
|
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.