Serilog.Sinks.File.Encrypt 5.0.0

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Serilog.Sinks.File.Encrypt --version 5.0.0
                    
NuGet\Install-Package Serilog.Sinks.File.Encrypt -Version 5.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Serilog.Sinks.File.Encrypt" Version="5.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Serilog.Sinks.File.Encrypt" Version="5.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Serilog.Sinks.File.Encrypt" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Serilog.Sinks.File.Encrypt --version 5.0.0
                    
#r "nuget: Serilog.Sinks.File.Encrypt, 5.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Serilog.Sinks.File.Encrypt@5.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Serilog.Sinks.File.Encrypt&version=5.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Serilog.Sinks.File.Encrypt&version=5.0.0
                    
Install as a Cake Tool

Serilog.Sinks.File.Encrypt

Build Status codecov NuGet NuGet Downloads License: MIT

A Serilog.File.Sink hook that encrypts log files using RSA and AES-GCM hybrid encryption. This package provides secure logging by encrypting log data before writing to disk, ensuring sensitive information remains protected.

v5.0.0 Breaking Changes Split the NuGet package Serilog.Sinks.File.Encrypt into 3 separate packages:

  • Serilog.Sinks.File.Encrypt (this package — the file hook for encryption only)
  • Serilog.Sinks.File.Decrypt (decryption library — LogReader, LocalKeyProvider, DecryptionOptions, DecryptionUtils, IKeyProvider)
  • Serilog.Sinks.File.Encrypt.Core (shared cryptographic primitives — transitive dependency, no direct reference needed)

Features

  • Hybrid Encryption: Uses RSA for key exchange and AES-GCM for efficient, authenticated data encryption
  • Key Rotation: Assign a key ID to EncryptHooks; the decryption layer selects the correct private key automatically
  • Seamless Integration: Plugs directly into Serilog.File.Sink using file lifecycle hooks
  • Optimal Performance: Optimized encryption performance using hybrid encryption

Use Cases

  • Secure logging of sensitive application data, especially in desktop applications
  • Compliance with data protection regulations by encrypting log files
  • Protection against unauthorized access to log files in shared or cloud environments

Performance

Production-ready performance with minimal overhead:

  • 8-12% time overhead in real-world unbuffered scenarios (well under typical targets)
  • 300K+ logs/second throughput with buffered writes (vs. ~174K baseline)
  • AES-GCM: ~1.03–1.07x memory overhead — near-baseline
  • ~5-16% throughput reduction with unbuffered encryption (148K–153K logs/sec)
  • 🚀 Buffered mode outperforms non-encrypted unbuffered by ~66% — encrypted buffered I/O is faster than plain unbuffered
  • Zero lock contentions — safe for multithreaded applications handled by Serilog.File.Sink

Buffering Trade-off: While buffered writes provide excellent performance, they carry a risk of data loss if the application crashes before flushing. Always call Log.CloseAndFlush() on application shutdown.

For detailed benchmarks and analysis, see the Benchmark Documentation.

Installation

Install the package via NuGet:

dotnet add package Serilog.Sinks.File.Encrypt

For decryption in your application, install the Decrypt package:

dotnet add package Serilog.Sinks.File.Decrypt

For key generation and ad-hoc log decryption, install the CLI tool:

dotnet tool install --global Serilog.Sinks.File.Encrypt.Cli

Quick Start

1. Generate RSA Key Pair

Generate an RSA key pair using the CLI tool:

serilog-encrypt generate --output ./keys

This creates:

  • public_key.xml: Used for encryption (safe to include with your application)
  • private_key.xml: Used for decryption (keep secure, do not distribute)

2. Configure Serilog with Encryption

using Serilog;
using Serilog.Sinks.File.Encrypt;

// Load your public key
string publicKeyXml = File.ReadAllText("./keys/public_key.xml");

// Configure Serilog with encryption.
// Assign a key ID to support future key rotation (recommended).
Log.Logger = new LoggerConfiguration()
    .WriteTo.File(
        path: "logs/app.log",
        hooks: new EncryptHooks(publicKeyXml, keyId: "my-app-key-2026"))
    .CreateLogger();

// Log as usual
Log.Information("This message will be encrypted!");

// Always flush on shutdown
Log.CloseAndFlush();

💡 Performance Tip: For high-volume scenarios where you can tolerate potential data loss on crashes, use buffered: true. See the Advanced Usage section below.

3. Decrypt Logs

To decrypt log files, see the Serilog.Sinks.File.Decrypt package for programmatic decryption, or the Serilog.Sinks.File.Encrypt.Cli tool for ad-hoc decryption.

Advanced Usage

High-Performance Configuration (Buffered Mode)

For high-volume logging scenarios where you can tolerate potential data loss on crashes:

using Serilog;
using Serilog.Sinks.File.Encrypt;

string publicKeyXml = File.ReadAllText("./keys/public_key.xml");

Log.Logger = new LoggerConfiguration()
    .WriteTo.File(
        path: "logs/app.log",
        buffered: true, // buffered writes
        flushToDiskInterval: TimeSpan.FromSeconds(5), // flush every X seconds (adjust as needed)
        hooks: new EncryptHooks(publicKeyXml, keyId: "my-app-key-2026"))
    .CreateLogger();

// CRITICAL: Always flush on shutdown
Log.CloseAndFlush();

⚠️ Warning: Buffered writes risk data loss on crashes. Only use when:

  • Application has reliable shutdown handling
  • You can tolerate loss of recent logs (up to flushToDiskInterval)
  • Performance is critical (background workers, high-volume systems)

⚠️ Minor Risks

  • Theoretical nonce reuse on crash with corrupted header (extremely low probability)
  • Nonce counter wrapping not explicitly handled (would require 2^96 encryptions per session)
    • At 1 million logs/second, this would take 2.5 trillion years to reach.

Key Rotation

Assign a unique keyId to each key generation cycle. The ID is embedded in every session header so the decryption layer knows which private key to use without any manual lookup.

// Old deployment — key from 2025
hooks: new EncryptHooks(oldPublicKey, keyId: "my-app-key-2025")

// New deployment — key from 2026
hooks: new EncryptHooks(newPublicKey, keyId: "my-app-key-2026")

For the decryption side of key rotation, see the Serilog.Sinks.File.Decrypt documentation.

Programmatic Key Generation

using Serilog.Sinks.File.Encrypt;

// Generate a new RSA key pair
var (publicKey, privateKey) = CryptographicUtils.GenerateRsaKeyPair();

// Save keys to files
File.WriteAllText("public_key.xml", publicKey);
File.WriteAllText("private_key.xml", privateKey);

Web Application Example

var builder = WebApplication.CreateBuilder(args);

// Load public key from configuration
string publicKeyXml = builder.Configuration["Logging:PublicKeyXml"]
    ?? throw new InvalidOperationException("Logging:PublicKeyXml is required");

builder.Host.UseSerilog((context, configuration) =>
    configuration
        .ReadFrom.Configuration(context.Configuration)
        .WriteTo.File(
            path: "logs/webapp-.log",
            rollingInterval: RollingInterval.Day,
            hooks: new EncryptHooks(publicKeyXml, keyId: "webapp-key-2026")));

var app = builder.Build();
app.Run();

API Reference

Key Management

// Generates a new RSA key pair with the specified key size and format (XML or PEM).
(string publicKey, string privateKey) CryptographicUtils.GenerateRsaKeyPair(int keySize = 2048, KeyFormat format = KeyFormat.Xml)

Encryption Hook

// publicKey — RSA public key in XML or PEM format
// keyId     — optional identifier embedded in every session header (max 32 bytes UTF-8); default ""
// version   — header format version; default 1 - Obsolete and has no effect anymore.
new EncryptHooks(string publicKey, string keyId = "", int version = 1)

Security Considerations

  • Keep private keys secure and never include them in your application deployment
  • Store private keys in secure key management systems in production (Azure Key Vault, AWS Secrets Manager, etc.)
  • Use 2048-bit RSA keys minimum (4096-bit for enhanced security)
  • Restrict filesystem access to encrypted log files and private keys
  • Rotate keys periodically and use the keyId parameter to track which key encrypted which files

Migration

For step-by-step migration guides, see the CHANGELOG.md:

Versioning

All packages in this repository (Serilog.Sinks.File.Encrypt, Serilog.Sinks.File.Decrypt, Serilog.Sinks.File.Encrypt.Cli, Serilog.Sinks.File.Encrypt.Core) are released in lockstep. Every package is versioned and published together on every release, even when a change only affects one of them. Always use the same version across all packages you reference.

Requirements

  • .NET 8.0 (LTS) or .NET 10.0 (LTS), or a compatible higher runtime
  • A project using Serilog.Sinks.File
  • RSA key pair in XML or PEM format (generated via CLI tool or programmatically)

Support policy: This library targets .NET Long-Term Support (LTS) releases only. A new LTS TFM is added when it ships; the oldest LTS TFM is dropped when Microsoft ends support for it. Users on STS or EOL runtimes can pin an older package version that targets a compatible LTS TFM.

Package Purpose
Serilog.Sinks.File.Decrypt Programmatic decryption of encrypted log files
Serilog.Sinks.File.Encrypt.Cli CLI tool for key generation and ad-hoc log decryption
Serilog.Sinks.File.Encrypt.Core Shared cryptographic primitives (transitive dependency)
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.1.0-preview.1 37 7/2/2026
5.0.0 94 6/29/2026
5.0.0-preview.4 51 6/29/2026
4.0.0 3,527 4/13/2026
4.0.0-preview.1 95 4/8/2026
3.0.0 1,080 3/23/2026
2.0.1-alpha.0.16 65 3/23/2026
2.0.0 4,147 12/2/2025
1.0.0 468 12/1/2025
0.50.1 237 11/27/2025
0.0.0-alpha.0.27 177 11/27/2025
0.0.0-alpha.0.17 185 11/25/2025
0.0.0-alpha.0.14 167 11/24/2025
0.0.0-alpha.0.13 174 11/24/2025
0.0.0-alpha.0.12 184 11/24/2025