BNN.KeyKet 1.0.2

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package BNN.KeyKet --version 1.0.2
                    
NuGet\Install-Package BNN.KeyKet -Version 1.0.2
                    
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="BNN.KeyKet" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BNN.KeyKet" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="BNN.KeyKet" />
                    
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 BNN.KeyKet --version 1.0.2
                    
#r "nuget: BNN.KeyKet, 1.0.2"
                    
#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 BNN.KeyKet@1.0.2
                    
#: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=BNN.KeyKet&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=BNN.KeyKet&version=1.0.2
                    
Install as a Cake Tool

KeyKet

Class library for hardware-backed cryptographic operations — TPM 2.0 and USB Token (PKCS#11) behind a single interface


Quick start

IKeyKetManager manager = KeyKetFactory.Create(new KeyKetOptions
{
    Provider      = KeyKetProviderType.Tpm,
    RootPath      = "/var/myapp",   // optional — defaults to AppData
    RsaKeyAccount = "device-001"
});

// or USB Token
IKeyKetManager manager = KeyKetFactory.Create(new KeyKetOptions
{
    Provider      = KeyKetProviderType.UsbToken,
    Pkcs11LibPath = "/usr/lib/softhsm/libsofthsm2.so",
    TokenSerial   = "ABC123",
    Pin           = "1234"
});

manager.Dispose(); // always dispose when done

Dependency Injection

Fixed provider (most common)

builder.Services.AddSingleton<IKeyKetManager>(_ =>
    KeyKetFactory.Create(new KeyKetOptions
    {
        Provider      = KeyKetProviderType.Tpm,
        RsaKeyAccount = "device-001"
    }));

Runtime-switchable provider

When you need to swap hardware without restarting, use SwitchableKeyKetManager. Register under both names — both resolve to the same singleton instance.

// Line 1: create the instance, register under concrete type
//         so any controller/service that needs SwitchTo() can inject this directly
builder.Services.AddSingleton<SwitchableKeyKetManager>(_ =>
    new SwitchableKeyKetManager(new KeyKetOptions
    {
        Provider      = KeyKetProviderType.Tpm,
        RsaKeyAccount = "device-001"
    }));

// Line 2: alias IKeyKetManager → same instance (no second object created)
//         ordinary services inject IKeyKetManager and never need to know about switching
builder.Services.AddSingleton<IKeyKetManager>(sp =>
    sp.GetRequiredService<SwitchableKeyKetManager>());
// Regular service — inject by interface, unaware of hardware details
public class SigningService(IKeyKetManager manager) { ... }

// Admin endpoint — inject concrete type to access SwitchTo()
[HttpPost("admin/switch")]
public IActionResult Switch(
    [FromServices] SwitchableKeyKetManager manager,
    [FromBody] KeyKetOptions options)
{
    manager.SwitchTo(options);                       // atomic swap, old instance auto-disposed
    return Ok(manager.CurrentProvider.ToString());
}

SwitchTo() uses Interlocked.Exchange — pointer swap is atomic.
Requests in flight at the moment of switch may receive an error — this is accepted behaviour.

Both providers simultaneously (.NET 8 keyed services)

builder.Services.AddKeyedSingleton<IKeyKetManager>("tpm",
    (_, _) => KeyKetFactory.Create(tpmOptions));
builder.Services.AddKeyedSingleton<IKeyKetManager>("usb",
    (_, _) => KeyKetFactory.Create(usbOptions));

public class MyService(
    [FromKeyedServices("tpm")] IKeyKetManager tpm,
    [FromKeyedServices("usb")] IKeyKetManager usb) { }

Always register as Singleton. TPM handles and PKCS#11 sessions are stateful hardware resources — never create per-request.


Return type

All methods return KeyKetCommonResult. Always check Success before using Data.

public class KeyKetCommonResult
{
    public string Data    { get; set; }   // result value when successful
    public string Error   { get; set; }   // error message when failed
    public bool   Success => Error == null;
}

var result = manager.GenerateAndGetPublicKey();
if (!result.Success)
    throw new Exception(result.Error);

string publicKey = result.Data;

API reference

GetDeviceUserSerial()

Returns a stable unique identifier for the current machine.

Returns Data = machine ID string

GenerateAndGetPublicKey()

Generates an RSA 2048 key pair on the hardware device if one does not exist, then returns the public key. Safe to call multiple times — only generates once.

Returns Data = Base64 DER encoded RSA public key serial

Send Data to your server so the server can encrypt SAD keys for this device.


CreateJWT(Dictionary<string, string> payload)

Creates a signed RS256 JWT using the device's own key pair.

payload Claims to embed — e.g. { "sub": "device-001", "exp": "..." }
Returns Data = full JWT string header.payload.signature
Algorithm RS256 — signed directly on hardware (TPM) or via PKCS#11 (USB Token)

SignSAD(byte[] encryptedKey, byte[] iv, byte[] blob, string sad)

Decrypts the SAD private key using the hardware device, then uses it to sign sad. The decrypted key is disposed immediately after signing.

Parameter Description
encryptedKey AES-256 key encrypted with this device's RSA public key (server-generated)
iv AES-CBC initialization vector (16 bytes)
blob SAD private key (PKCS#8) encrypted with the AES key above
sad The data to sign — auto-detected as JWT, XML (Base64), or binary (Base64)
sad format Detection Data returned
JWT Splits into ≥ 2 parts, header/payload are valid Base64url JSON Completed JWT header.payload.signature
XML Decodes as Base64 → valid XML Original XML with <Signature> node appended, re-encoded as Base64
Binary Everything else Base64 signature bytes

CreateCSR(byte[] encryptedKey, byte[] iv, byte[] blob, string subjectName)

Decrypts the SAD private key (same mechanism as SignSAD) and creates a PKCS#10 Certificate Signing Request.

Parameter Description
encryptedKey AES key encrypted with device RSA public key
iv AES-CBC IV (16 bytes)
blob SAD private key (PKCS#8) encrypted with AES key
subjectName X.500 subject — e.g. "CN=device-001, O=MyCompany, C=VN"
Returns Data = Base64 DER encoded PKCS#10 CSR

Submit Data to your CA to receive a signed certificate.


Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  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 is compatible.  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 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 was computed.  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