OpenKMS 1.3.0

.NET 6.0
dotnet add package OpenKMS --version 1.3.0
NuGet\Install-Package OpenKMS -Version 1.3.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="OpenKMS" Version="1.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add OpenKMS --version 1.3.0
#r "nuget: OpenKMS, 1.3.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install OpenKMS as a Cake Addin
#addin nuget:?package=OpenKMS&version=1.3.0

// Install OpenKMS as a Cake Tool
#tool nuget:?package=OpenKMS&version=1.3.0

Open KMS SDK

NuGet Verify

The OpenKMS .NET SDK for .NET 6+.

Installation

Using the .NET Core command-line interface (CLI) tools:

dotnet add package OpenKMS

Using the NuGet Command Line Interface (CLI):

nuget install OpenKMS

Using the Package Manager Console:

Install-Package OpenKMS

Documentation

OpenKMS is an encryption abstraction based on the Json Web Encryption (JWE), Json Web Algorithm (JWA), and Json Web Key (JWK) specifications. The IEncryptionService interface exposes methods for encrypt and decrypt operations.

public interface IEncryptionService
{
    Task<JsonWebEncryption> EncryptAsync(byte[] plaintext, string? scheme, CancellationToken cancellationToken = default);
    Task<JsonWebEncryption> EncryptAsync(string plaintext, string? scheme, CancellationToken cancellationToken = default);

    Task<byte[]> DecryptAsync(JsonWebEncryption encryption, CancellationToken cancellationToken = default);
    Task<string> DecryptStringAsync(JsonWebEncryption encryption, CancellationToken cancellationToken = default);
}

Encryption schemes are used to register encryption handlers and pre-configure options (e.g. KeyType, KeySize, Algorithm) used when calling EncryptAsync.

// IServiceCollection services;

services.AddEncryption(o =>
{
    o.DefaultScheme = "default";
}).AddScheme<AesEncryptionOptions, AesEncryptionHandler, AzureKeyVaultEncryptionOptions, AzureKeyVaultEncryptionHandler>("default", 
    contentEncryptionOptions => {
        contentEncryptionOptions.EncryptionAlgorithm = EncryptionAlgorithm.A256CBC_HS512;
        contentEncryptionOptions.KeySize = 256;
        contentEncryptionOptions.KeyType = KeyType.OCT;
    },
    keyEncrptionOptions => {
        keyEncrptionOptions.KeySize = 4096;
        keyEncrptionOptions.KeyType = KeyType.RSA;
        keyEncrptionOptions.KeyName = "<key_name>";
        keyEncrptionOptions.EncryptionAlgorithm = EncryptionAlgorithm.RSA_OAEP;
    }
);

To derive a new encryption handler implementation, extend the EncryptionHandler<TOptions> and EncryptionHandlerOptions abstract classes.

Provide handler implementations for:

  • Task<EncryptResult> EncryptAsync(byte[], byte[]?, CancellationToken)
  • Task<byte[]> DecryptAsync(JsonWebKey, byte[], byte[]?, byte[]?, byte[]?, CancellationToken)
  • bool CanDecrypt(JsonWebKey)

Provide options implementations for:

  • IList<EncryptionAlgorithm> ValidEncryptionAlgorithms
  • Dictionary<KeyType, int?[]> ValidKeyTypeSizes
  • EncryptionAlgorithm EncryptionAlgorithm
  • KeyType KeyType
  • int? KeySize

Usage

Dependency Injection

To configure an instance of IEncryptionService that can be used throughout your project, call AddEncryption when registering services:

// program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddEncryption()
    .AddScheme<TContentEncryptionOptions, TContentHander, TKeyEncryptionOptions, TKeyHandler>("<scheme_name>",
        contentEncrptionOptions => { ... },
        keyEncryptionOptions => { ... }
    ); // calls can be chained to .AddScheme<> to register more encryption schemes!

To inject an instance of IEncryptionHandler into your class for data encryption and/or decryption, add a constructor dependency for IEncryptionService.

public class MyAwesomeService() {
    private readonly IEncryptionService _encryptionService;
    private readonly IPersonRepository _repository;
    
    public MyAwesomeService(IEncryptionService encryptionService, IPersonRepository repository) {
        _encryptionService = encryptionService;
        _repository = repository;
    }
    
    public async Task SavePerson(Person person, CancellationToken cancellationToken = default) {
        JsonWebEncryption encryptedName = await _encryptionService.EncryptAsync(
            person.Name,
            "<scheme_name>",
            cancellationToken);
        
        person.Name = null;
        person.NameEncrypted = encryptedName.ToCompactSerializationFormat();
        
        await _repository.SavePersonAsync(person, cancellationToken);
    }
    
    public async Task<Person> GetPersonById(string personId, CancellationToken cancellationToken = default) {
        var foundPerson = await _repository.GetPersonAsync(personId, cancellationToken);
        
        JsonWebEncryption encryptedName = JsonWebEncryption.FromCompactSerializationFormat(person.NameEncrypted);
        var decryptedName = await _encryptionService.DecryptAsync(encryptedName, cancellationToken);
        
        person.Name = Encoding.UTF8.GetString(decryptedName);
        person.NameEncrypted = null;
    
        return person;
    }
}

Entity Framework

To automatically encrypt and decrypt a property when utilizing Entity Framework Core, you may optionally annotate your data models with the Encrypted attribute:

public class Bank
{
	public int Id { get; set; }
	
	[Encrypted] // Utilizes registered DefaultScheme
	public string RoutingNumber { get; set; }
	
	[Encrypted("AccountNumber")] // Utilizes registered AccountNumber scheme
	public string AccountNumber { get; set; }
}

You can then register the encryption service with your Entity Framework DbContext:

public class DatabaseContext : DbContext
{
	private readonly IEncryptionService _encryptionService;

	public DbSet<Bank> Banks { get; set; }
	
	public DatabaseContext(DbContextOptions options, IEncryptionService encryptionService)
		: base(options)
	{
		_encryptionService = encryptionService;
	}
	
	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.UseEncryption(_encryptionService);
	}
}

Development

The provided scripts with the SDK will check for all dependencies, start docker, build the solution, and run all tests.

Dependencies

Build the SDK and run Tests

Run the following command from the root of the project:

make verify
Product Versions
.NET net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on OpenKMS:

Package Downloads
OpenKMS.Azure.KeyVault

OpenKMS Azure KeyVault encryption service provider

OpenKMS.Aes

OpenKMS library for AES Encryption Algorithms

OpenKMS.EntityFrameworkCore

Package Description

OpenKMS.AWS.KeyManagementService

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.0 403 9/26/2022
1.2.0 382 8/19/2022
1.1.0 388 8/19/2022
1.0.2 319 8/19/2022
1.0.1 318 8/19/2022
1.0.0 316 8/19/2022