Serilog.Sinks.File.Decrypt 5.0.0-preview.4

This is a prerelease version of Serilog.Sinks.File.Decrypt.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Serilog.Sinks.File.Decrypt --version 5.0.0-preview.4
                    
NuGet\Install-Package Serilog.Sinks.File.Decrypt -Version 5.0.0-preview.4
                    
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.Decrypt" Version="5.0.0-preview.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Serilog.Sinks.File.Decrypt" Version="5.0.0-preview.4" />
                    
Directory.Packages.props
<PackageReference Include="Serilog.Sinks.File.Decrypt" />
                    
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.Decrypt --version 5.0.0-preview.4
                    
#r "nuget: Serilog.Sinks.File.Decrypt, 5.0.0-preview.4"
                    
#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.Decrypt@5.0.0-preview.4
                    
#: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.Decrypt&version=5.0.0-preview.4&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Serilog.Sinks.File.Decrypt&version=5.0.0-preview.4&prerelease
                    
Install as a Cake Tool

Serilog.Sinks.File.Decrypt

Build Status NuGet NuGet Downloads License: MIT

A library for decrypting log files encrypted with Serilog.Sinks.File.Encrypt.

v5.0.0 — New package Decryption types have moved out of Serilog.Sinks.File.Encrypt into this package. Namespaces have changed:

v4.x (Serilog.Sinks.File.Encrypt) v5.0.0 (Serilog.Sinks.File.Decrypt)
LogReader LogReader
LocalKeyProvider LocalKeyProvider
Models.DecryptionOptions Models.DecryptionOptions
Models.DecryptionResult Models.DecryptionResult
Models.ErrorHandlingMode Models.ErrorHandlingMode
Interfaces.IKeyProvider Interfaces.IKeyProvider
CryptographicUtils.DecryptLogFileAsync(...) DecryptionUtils.DecryptLogFileAsync(...)

Installation

dotnet add package Serilog.Sinks.File.Decrypt

For ad-hoc decryption from the command line, install the CLI tool:

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

Quick Start

using Serilog.Sinks.File.Decrypt;
using Serilog.Sinks.File.Decrypt.Models;

// Load your RSA private key
string privateKey = File.ReadAllText("private_key.xml");

var options = new DecryptionOptions
{
    KeyProvider = new LocalKeyProvider("my-app-key-2026", privateKey)
};

// Decrypt a file
DecryptionResult result = await DecryptionUtils.DecryptLogFileAsync(
    "logs/app.log",
    "logs/app-decrypted.log",
    options
);

Key Rotation

When your application has rotated keys over time, supply all active private keys to LocalKeyProvider. The key ID embedded in each session header selects the correct key automatically.

using Serilog.Sinks.File.Decrypt;
using Serilog.Sinks.File.Decrypt.Models;

string oldPrivateKey = File.ReadAllText("./keys/private_key_2025.xml");
string newPrivateKey = File.ReadAllText("./keys/private_key_2026.xml");

var keyMap = new Dictionary<string, string>
{
    { "my-app-key-2025", oldPrivateKey },
    { "my-app-key-2026", newPrivateKey },
};

using LocalKeyProvider keyProvider = new LocalKeyProvider(keyMap);
var options = new DecryptionOptions { KeyProvider = keyProvider };

await DecryptionUtils.DecryptLogFileAsync("logs/app.log", "logs/app-decrypted.log", options);

The CLI tool only supports one key per invocation. For mixed-key directories, use LocalKeyProvider with a full key map as shown above, or implement IKeyProvider to integrate with your key management system.

Programmatic Decryption

using Serilog.Sinks.File.Decrypt;
using Serilog.Sinks.File.Decrypt.Models;

var keyMap = new Dictionary<string, string>
{
    { "my-app-key-2026", File.ReadAllText("private_key.xml") },
};
using LocalKeyProvider keyProvider = new LocalKeyProvider(keyMap);

var options = new DecryptionOptions { KeyProvider = keyProvider };

// File-to-file
await DecryptionUtils.DecryptLogFileAsync("logs/app.log", "logs/decrypted.log", options);

// Stream-to-stream (memory-efficient for large files)
using var input  = File.OpenRead("large-log.encrypted");
using var output = File.Create("large-log.decrypted");
await DecryptionUtils.DecryptLogFileAsync(input, output, options);

Error Handling

Choose how the decryption engine responds to corrupted or unreadable sections:

// Skip corrupted sections silently (DEFAULT — recommended for production)
var skipOptions = new DecryptionOptions
{
    KeyProvider = keyProvider,
    ErrorHandlingMode = ErrorHandlingMode.Skip
};

// With audit logging — pass any Serilog ILogger to capture error details
ILogger auditLogger = new LoggerConfiguration()
    .WriteTo.File("decryption-audit.log")
    .CreateLogger();
await DecryptionUtils.DecryptLogFileAsync(input, output, skipOptions, auditLogger);

// Throw on first error (strict validation)
var strictOptions = new DecryptionOptions
{
    KeyProvider = keyProvider,
    ErrorHandlingMode = ErrorHandlingMode.ThrowException
};

try
{
    await DecryptionUtils.DecryptLogFileAsync(input, output, strictOptions);
}
catch (CryptographicException ex)
{
    Console.WriteLine($"Decryption failed: {ex.Message}");
}

Custom Key Provider

Implement IKeyProvider to integrate with external key management systems (Azure Key Vault, AWS KMS, etc.):

using Serilog.Sinks.File.Decrypt.Interfaces;

public class AzureKeyVaultProvider : IKeyProvider
{
    public async Task<byte[]> DecryptAsync(
        string keyId,
        ReadOnlyMemory<byte> cipherText,
        CancellationToken cancellationToken = default)
    {
        // Use Azure SDK to decrypt with the key identified by keyId
        // ...
    }

    public async Task<int> GetKeySizeAsync(
        string keyId,
        CancellationToken cancellationToken = default)
    {
        // Return the RSA key size in bits for the given keyId
        // ...
    }
}

API Reference

DecryptionUtils

// Stream-to-stream async decryption
Task<DecryptionResult> DecryptionUtils.DecryptLogFileAsync(
    Stream inputStream,
    Stream outputStream,
    DecryptionOptions options,
    ILogger? logger = null,
    CancellationToken cancellationToken = default)

// File-to-file async decryption
Task<DecryptionResult> DecryptionUtils.DecryptLogFileAsync(
    string encryptedFilePath,
    string outputFilePath,
    DecryptionOptions options,
    ILogger? logger = null,
    CancellationToken cancellationToken = default)

IKeyProvider

public interface IKeyProvider
{
    // Decrypts the AES-GCM session key using the RSA private key for the given keyId.
    Task<byte[]> DecryptAsync(
        string keyId,
        ReadOnlyMemory<byte> cipherText,
        CancellationToken cancellationToken = default);

    // Returns the RSA key size in bits for the given keyId.
    // Used to determine how many bytes to read from the session header.
    Task<int> GetKeySizeAsync(string keyId, CancellationToken cancellationToken = default);
}

DecryptionOptions

public sealed record DecryptionOptions
{
    public required IKeyProvider KeyProvider { get; init; }
    public ErrorHandlingMode ErrorHandlingMode { get; init; } = ErrorHandlingMode.Skip;
}

ErrorHandlingMode

public enum ErrorHandlingMode
{
    Skip           = 0,  // Skip corrupted sections silently (DEFAULT)
    ThrowException = 1   // Throw CryptographicException on first error
}

DecryptionResult

public class DecryptionResult
{
    public int DecryptedSessions { get; init; }
    public int DecryptedMessages { get; init; }
    public int FailedHeaders     { get; init; }
    public int FailedMessages    { get; init; }
    public int ResyncAttempts    { get; init; }
}

Security Considerations

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

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

Package Purpose
Serilog.Sinks.File.Encrypt Encrypts log files written by Serilog
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
6.0.0-preview.1 0 7/6/2026
5.1.0-preview.1 43 7/2/2026
5.0.0 90 6/29/2026
5.0.0-preview.4 55 6/29/2026