CipherShift365 Vault SDK
Package: CipherShift365.Vault
Target: .NET 9 / .NET 10
Role: Post-quantum cryptographic operations SDK — key encapsulation, digital signatures, symmetric policy enforcement, provider registry, config-driven switching, hybrid mode, key rotation, secure memory management.
Table of Contents
- What It Does
- Why It's Needed (Value Proposition)
- Installation
- How to Run / Use
- User Manual
- Developer Manual
- Code Examples
- API Reference
- Configuration Options
What It Does
The Vault SDK provides a unified, provider-abstracted cryptographic operations layer for post-quantum algorithms. It enables applications to perform key encapsulation, digital signing, and symmetric encryption policy enforcement — decoupled from the underlying implementation.
Core Capabilities
Key Encapsulation (
IKem,IKemProvider) — ML-KEM-768/1024 encapsulation and decapsulation. Cryptographic agility: swap providers without changing application code.Digital Signatures (
ISignature,ISignatureProvider) — ML-DSA-44/65/87 and SLH-DSA signing and verification. SupportsPureandHybridmodes.Composite / Hybrid Mode — Combines classical (RSA/ECDSA) and post-quantum signatures into a single verifiable hybrid artifact. Fails closed — if any component fails verification, the entire artifact is rejected.
Symmetric Policy (
ISymmetric,SymmetricPolicy) — Enforces minimum key size policies (default 256 bits). Validates AES, ChaCha20, and any symmetric algorithm against a configurable threshold.Provider Registry (
IProviderRegistry) — Pluggable architecture where algorithm names resolve to concrete providers. Supports runtime registration and config-driven switching.Configuration-Driven Switching (
ConfigurationProviderRegistry) — Maps algorithm names to provider types with validation requirements. Changing config changes behavior without recompilation.Key Store (
IKeyStore) — Abstracts key retrieval. Ships withInMemoryKeyStorefor development. Extensible for Azure Key Vault, HSM, or database backends.Key Rotation (
KeyRotationManager) — Tracks key lifetimes, deprecation windows, and expiry. Produces rotation status (Active,Deprecated,Expired).Secure Memory (
SecureMemory) — Utilities for zeroing sensitive buffers and minimizing secret lifetimes usingCryptographicOperations.ZeroMemory.Crypto Events (
ICryptoEventSource) — Diagnostic event emission for auditing, logging, and compliance reporting.
Provider Implementations
| Provider | Algorithm | Backend | Status |
|---|---|---|---|
NativeMlKemProvider |
ML-KEM-768/1024 | .NET 10 MLKem API |
Placeholder (awaiting .NET 10 GA) |
NativeMlDsaProvider |
ML-DSA-65 | .NET 10 MLDsa API |
Placeholder (awaiting .NET 10 GA) |
BouncyCastleKemProvider |
ML-KEM-768 | BouncyCastle PQC | Placeholder (BC integration TBD) |
BouncyCastleSignatureProvider |
ML-DSA-65 | BouncyCastle PQC | Placeholder (BC integration TBD) |
Why It's Needed
Applications built today must survive the quantum transition. That means adopting ML-KEM, ML-DSA, and SLH-DSA — algorithms with fundamentally different APIs than RSA and ECDSA. The Vault SDK provides:
- Application-level cryptographic agility. Swap from software to HSM, or from BouncyCastle to native .NET 10, by changing a config file, not your code.
- Hybrid mode for transitional security. Run classical + PQC signatures simultaneously during migration, verifying both. Fails closed — hybrid is all-or-nothing.
- Hardened secret management. Secure memory, key rotation, and event auditing prevent common secret-handling mistakes.
- Compliance readiness. Symmetric policy enforcement ensures all encryption meets CNSA 2.0 minimums (AES-256). Provider validation status is tracked and configurable.
Value Showcase
| Capability | Value |
|---|---|
| Algorithm agility | Change KEM/signature algorithm by changing config or registry registration |
| Hybrid verification | Verify classical + PQC signatures together; fail closed if either is missing or invalid |
| Provider pinning | Lock specific algorithms to specific providers (e.g., "ML-DSA-65 must use native .NET 10") |
| Config-driven defaults | DefaultKem, DefaultSignature through CryptoConfig |
| Key rotation lifecycle | Track creation, deprecation, and expiry with automated status checks |
| Secure memory | CryptographicOperations.ZeroMemory wrappers for secret buffers |
| Event auditing | Every cryptographic operation emits a diagnostic event for SIEM ingestion |
| Validation gating | Providers carry ValidationStatus; config can require Validated only |
Installation
<PackageReference Include="CipherShift365.Vault" Version="1.0.0" />
Transitive dependencies include:
CipherShift365.Core.Runtime- BouncyCastle (for experimental PQC provider support)
dotnet add package CipherShift365.Vault
How to Run / Use
Basic Setup
using CipherShift365.Core.Runtime;
using CipherShift365.Vault;
using CipherShift365.Vault.Providers;
// 1. Create infrastructure
var keyStore = new InMemoryKeyStore();
var events = new DiagnosticCryptoEventSource();
var headerCodec = new ArtifactHeaderCodec();
var registry = new ProviderRegistry();
// 2. Register providers
var bouncyKem = new BouncyCastleKemProvider("ML-KEM-768");
var bouncySig = new BouncyCastleSignatureProvider("ML-DSA-65");
registry.Register(bouncyKem);
registry.Register(bouncySig);
// 3. Create services
var kem = new CompositeKem(registry);
var signature = new CompositeSignature(registry, headerCodec, events);
// 4. Use
var result = await kem.EncapsulateAsync(new PublicKeyRef("key-001", "ML-KEM-768"));
Console.WriteLine($"Shared secret: {result.SharedSecret.Length} bytes");
Symmetric Policy Enforcement
var policy = new SymmetricPolicy(minimumKeySize: 256);
var result1 = policy.ValidatePolicy("AES-256-GCM", new CryptoParameters(KeySize: 256));
Console.WriteLine(result1.IsCompliant); // True
var result2 = policy.ValidatePolicy("AES-128", new CryptoParameters(KeySize: 128));
Console.WriteLine(result2.IsCompliant); // False
Console.WriteLine(result2.Reason);
// "Key size 128 is below minimum 256 bits. Use AES-256 or higher."
User Manual
Key Encapsulation (KEM)
KEM is the post-quantum replacement for RSA/ECDH key exchange. The Vault SDK abstracts KEM behind two interfaces:
IKemProvider — The low-level per-algorithm interface:
Task<EncapsulationResult> EncapsulateAsync(PublicKeyRef recipient, CancellationToken ct);
Task<ReadOnlyMemory<byte>> DecapsulateAsync(KeyRef privateKey, ReadOnlyMemory<byte> ciphertext, CancellationToken ct);
IKem (via CompositeKem) — The application-level interface:
Task<EncapsulationResult> EncapsulateAsync(PublicKeyRef recipient, CancellationToken ct);
Task<ReadOnlyMemory<byte>> DecapsulateAsync(KeyRef privateKey, ReadOnlyMemory<byte> ciphertext, CancellationToken ct);
CompositeKem resolves the provider from PublicKeyRef.Algorithm (defaults to "ML-KEM-768") and delegates.
EncapsulationResult: Contains Ciphertext (the encapsulated key) and SharedSecret (the derived symmetric key). Both are ReadOnlyMemory<byte> — callers should copy before the buffer is cleared.
Digital Signatures
ISignatureProvider — Per-algorithm:
Task<SignedArtifact> SignAsync(KeyRef, Stream, SignOptions, CancellationToken);
Task<VerificationResult> VerifyAsync(Stream, SignedArtifact, CancellationToken);
ISignature (via CompositeSignature) — Application-level:
Task<SignedArtifact> SignAsync(KeyRef, Stream, SignOptions, CancellationToken);
Task<VerificationResult> VerifyAsync(Stream, SignedArtifact, CancellationToken);
SignOptions: Controls signature mode and scheme.
| Property | Type | Default | Description |
|---|---|---|---|
Mode |
CryptoMode |
Hybrid |
Pure (single algo) or Hybrid (multi-component) |
SchemeId |
string? |
null |
Named scheme identifier for hybrid artifacts |
Hybrid Mode
Hybrid mode combines classical and post-quantum signatures. The artifact's ArtifactHeader.SchemeId encodes the component algorithms separated by + (e.g., "ECDSA+ML-DSA-65").
Signing: The signer produces a single signature with both components.
Verification: CompositeSignature.VerifyAsync detects CryptoMode.Hybrid in the header and:
- Checks that
SchemeIdis present and contains at least 2 components - Verifies all components resolve to registered providers
- Verifies every component independently
- Returns
VerificationOutcome.Tamperedif any step fails — fails closed
Provider Registration
Providers are registered by algorithm name (case-insensitive):
var registry = new ProviderRegistry();
registry.Register(new BouncyCastleKemProvider("ML-KEM-768"));
registry.Register(new BouncyCastleKemProvider("ML-KEM-1024"));
registry.Register(new BouncyCastleSignatureProvider("ML-DSA-44"));
registry.Register(new BouncyCastleSignatureProvider("ML-DSA-65"));
registry.Register(new BouncyCastleSignatureProvider("ML-DSA-87"));
Resolution:
var kem768 = registry.ResolveKem("ML-KEM-768"); // succeeds
var kem1024 = registry.ResolveKem("ML-KEM-1024"); // succeeds
var bad = registry.ResolveKem("RSA"); // throws InvalidOperationException
Safe resolution with TryResolve:
if (registry.TryResolveKem("ML-KEM-1024", out var provider))
await provider.EncapsulateAsync(recipient);
Configuration-Driven Switching
Wrap any IProviderRegistry with ConfigurationProviderRegistry:
var config = new CryptoConfig(
KemProviders: new[]
{
new CryptoConfigEntry("ML-KEM-768", "Native", Pinnable: true, Pinned: true,
MinimumValidation: ValidationStatus.Validated),
new CryptoConfigEntry("ML-KEM-1024", "BouncyCastle",
MinimumValidation: ValidationStatus.Validated),
},
SignatureProviders: new[]
{
new CryptoConfigEntry("ML-DSA-65", "Native", Pinnable: true,
MinimumValidation: ValidationStatus.Validated),
},
RequireValidatedProviders: true,
DefaultKem: "ML-KEM-768",
DefaultSignature: "ML-DSA-65");
var configRegistry = new ConfigurationProviderRegistry(innerRegistry, config);
The ConfigurationProviderRegistry validates every provider resolution against the config:
RequireValidatedProviders: true— throws if any provider is notValidatedMinimumValidation— throws if the provider's validation is below the required levelPinned: true— the config entry is designated as the pinned choice (informational)
Symmetric Policy
SymmetricPolicy enforces minimum key sizes:
var policy = new SymmetricPolicy(256); // CNSA 2.0 minimum
ValidatePolicy checks both:
- The explicit
CryptoParameters.KeySizevalue - The algorithm name (algorithms without "256" in the name are flagged if no explicit key size is provided)
Key Rotation
Define a rotation policy and track keys:
var policy = new KeyRotationPolicy(
MaximumKeyLifetime: TimeSpan.FromDays(90),
DeprecationWindow: TimeSpan.FromDays(30),
RequireRotationBeforeExpiry: true);
var manager = new KeyRotationManager(policy);
var meta = manager.RegisterKey("signing-key-001", "ML-DSA-65", keySize: null);
// After 60 days...
var status = manager.CheckRotationStatus("signing-key-001");
// status == KeyRotationStatus.Active
// After 65 days...
status = manager.CheckRotationStatus("signing-key-001");
// status == KeyRotationStatus.Deprecated
// After 95 days...
status = manager.CheckRotationStatus("signing-key-001");
// status == KeyRotationStatus.Expired
Secure Memory
byte[] secret = RandomNumberGenerator.GetBytes(32);
// Use the secret...
// Clear it when done
SecureMemory.Clear(secret);
// All bytes are now zero
// Copy and clear source in one step
byte[] copy = SecureMemory.CopyAndClear(secret);
// secret is zeroed; copy contains the original value
Crypto Events
Every cryptographic operation emits an event via ICryptoEventSource:
public interface ICryptoEventSource
{
void Emit(CryptoEvent evt);
}
Common event types:
Sign.Start,Sign.Success,Sign.FailVerify.Start,Verify.Component,Verify.Success,Verify.FailMlKem.Encapsulate,MlKem.DecapsulateMlDsa.Sign,MlDsa.Verify
Events carry the algorithm, role, mode, key ID, and optional details. Integrate with your logging/SIEM by implementing ICryptoEventSource.
Developer Manual
Architecture
CipherShift365.Vault
├── Contracts/
│ ├── IKem.cs # Application-level KEM interface
│ ├── ISignature.cs # Application-level signature interface
│ ├── ISymmetric.cs # Symmetric policy interface
│ ├── IKemProvider.cs # Per-algorithm KEM provider
│ ├── ISignatureProvider.cs # Per-algorithm signature provider
│ ├── IProviderRegistry.cs # Provider lookup & registration
│ ├── IKeyStore.cs # Key retrieval abstraction
│ ├── ICryptoEventSource.cs # Diagnostic event emitter
│ └── IArtifactHeaderCodec.cs # Artifact header serialization
├── Services/
│ ├── CompositeKem.cs # KEM facade with provider resolution
│ ├── CompositeSignature.cs # Signature facade with hybrid verification
│ ├── ProviderRegistry.cs # In-memory provider registry
│ ├── ConfigurationProviderRegistry.cs # Config-driven registry wrapper
│ ├── KeyRotationManager.cs # Key lifecycle tracking
│ ├── SecureMemory.cs # Zero-memory utilities
│ ├── InMemoryKeyStore.cs # Thread-safe in-memory key store
│ ├── DiagnosticCryptoEventSource.cs # Default event emitter
│ └── ArtifactHeaderCodec.cs # ArtifactHeader stream codec
├── Providers/
│ ├── NativeMlKemProvider.cs # .NET 10 ML-KEM (placeholder)
│ ├── NativeMlDsaProvider.cs # .NET 10 ML-DSA (placeholder)
│ └── BouncyCastleProviders.cs # BouncyCastle KEM + Signature providers
├── ProviderInfo.cs # Provider metadata record
├── SignOptions.cs # Signing configuration
└── CryptoConfig.cs # Config records (in ConfigurationProviderRegistry.cs)
Provider Interface Design
Every provider implements both the algorithm-specific contract and carries metadata:
public interface IKemProvider
{
string Algorithm { get; } // e.g., "ML-KEM-768"
ProviderInfo Info { get; } // Name, experimental flag, validation status
Task<EncapsulationResult> EncapsulateAsync(...);
Task<ReadOnlyMemory<byte>> DecapsulateAsync(...);
}
ProviderInfo:
public sealed record ProviderInfo(
string Name,
bool IsExperimental,
ValidationStatus Validation);
// ValidationStatus: NotValidated, Validated, Failed
Implementing a Custom Provider
public sealed class HsmKemProvider : IKemProvider
{
public string Algorithm => "ML-KEM-768";
public ProviderInfo Info { get; }
private readonly IKeyStore _keyStore;
public HsmKemProvider(IKeyStore keyStore, ICryptoEventSource events)
{
_keyStore = keyStore;
Info = new ProviderInfo("HSM ML-KEM-768", false, ValidationStatus.Validated);
}
public async Task<EncapsulationResult> EncapsulateAsync(
PublicKeyRef recipient, CancellationToken ct = default)
{
// HSM-specific encapsulation logic
// Retrieve public key from key store
// Call HSM PKCS#11 or REST API
// Return EncapsulationResult
}
public async Task<ReadOnlyMemory<byte>> DecapsulateAsync(
KeyRef privateKey, ReadOnlyMemory<byte> ciphertext, CancellationToken ct = default)
{
// HSM-specific decapsulation logic
}
}
Register it:
registry.Register(new HsmKemProvider(keyStore, events));
Hybrid Verification Flow
VerifyAsync(content, signature)
├─► Check signature.Header.Mode == Hybrid?
│ ├─► Yes: Check SchemeId exists and has ≥2 components
│ ├─► Verify all components resolve to registered providers
│ ├─► Verify each component sequentially
│ │ └─► Any component fails → return Tampered (fail closed)
│ └─► All components pass → return Valid
│ └─► No (Pure mode): Resolve single provider, verify, return result
└─► Return VerificationResult
Provider Pinning
The ConfigurationProviderRegistry supports provider pinning via CryptoConfigEntry.Pinned. When a config entry is pinned, it signals that this specific provider implementation is the preferred (or required) choice for the algorithm. The Pinnable flag indicates the algorithm/implementation pairing is suitable for pinning (stable, validated).
Key Rotation Lifecycle
Registration → Active → Deprecated → Expired
|_________________| (MaximumKeyLifetime)
|__________| (DeprecationWindow)
- Active: Key is valid for use
- Deprecated: Key should be rotated but is still usable (migration window)
- Expired: Key must not be used
Code Examples
Complete Vault Setup
// Infrastructure
var keyStore = new InMemoryKeyStore();
var events = new DiagnosticCryptoEventSource();
var headerCodec = new ArtifactHeaderCodec();
var registry = new ProviderRegistry();
// Register PQC providers
registry.Register(new BouncyCastleKemProvider("ML-KEM-768"));
registry.Register(new BouncyCastleKemProvider("ML-KEM-1024"));
registry.Register(new BouncyCastleSignatureProvider("ML-DSA-65"));
// Wrap with config validation
var config = new CryptoConfig(
KemProviders: new[]
{
new CryptoConfigEntry("ML-KEM-768", "BouncyCastle",
MinimumValidation: ValidationStatus.Validated),
},
SignatureProviders: new[]
{
new CryptoConfigEntry("ML-DSA-65", "BouncyCastle",
MinimumValidation: ValidationStatus.Validated),
},
RequireValidatedProviders: true);
var configRegistry = new ConfigurationProviderRegistry(registry, config);
// Application-level services
var kem = new CompositeKem(configRegistry);
var signature = new CompositeSignature(configRegistry, headerCodec, events);
var symmetricPolicy = new SymmetricPolicy(256);
var rotationManager = new KeyRotationManager(
new KeyRotationPolicy(TimeSpan.FromDays(90), TimeSpan.FromDays(30)));
// Store keys
keyStore.Store("app-signing-key",
new KeyRef("app-signing-key", "ML-DSA-65"),
new PublicKeyRef("app-signing-key", "ML-DSA-65"));
rotationManager.RegisterKey("app-signing-key", "ML-DSA-65");
Signing and Verifying (Hybrid Mode)
// Sign content
using var content = new MemoryStream(Encoding.UTF8.GetBytes("Important data"));
var signOptions = new SignOptions(
Mode: CryptoMode.Hybrid,
SchemeId: "ECDSA+ML-DSA-65");
var signingKey = new KeyRef("app-signing-key", "ML-DSA-65");
var signed = await signature.SignAsync(signingKey, content, signOptions);
Console.WriteLine($"Header mode: {signed.Header.Mode}"); // Hybrid
Console.WriteLine($"Scheme: {signed.Header.SchemeId}"); // ECDSA+ML-DSA-65
// Verify
content.Position = 0;
var verifyResult = await signature.VerifyAsync(content, signed);
Console.WriteLine($"Valid: {verifyResult.IsValid}"); // True
KEM Key Exchange
// Alice encapsulates to Bob's public key
var bobPublicKey = new PublicKeyRef("bob-key-001", "ML-KEM-768");
var encapsulation = await kem.EncapsulateAsync(bobPublicKey);
// Send ciphertext to Bob...
// Bob decapsulates
var bobPrivateKey = new KeyRef("bob-key-001", "ML-KEM-768");
var sharedSecret = await kem.DecapsulateAsync(bobPrivateKey, encapsulation.Ciphertext);
// Alice and Bob now share the same secret
// Use sharedSecret as an AES-256 key
Policy Enforcement in Application Code
public class SecureChannel
{
private readonly ISymmetric _policy;
private readonly CompositeKem _kem;
public SecureChannel(ISymmetric policy, CompositeKem kem)
{
_policy = policy;
_kem = kem;
}
public async Task<byte[]> EstablishSessionKeyAsync(PublicKeyRef peer)
{
var result = await _kem.EncapsulateAsync(peer);
// Enforce symmetric policy on the derived key
var validation = _policy.ValidatePolicy("AES-256-GCM",
new CryptoParameters(KeySize: result.SharedSecret.Length * 8));
if (!validation.IsCompliant)
throw new CryptographicException(validation.Reason!);
return result.SharedSecret.ToArray();
}
}
Key Rotation Check
var rotationManager = new KeyRotationManager(
new KeyRotationPolicy(TimeSpan.FromDays(90), TimeSpan.FromDays(30)));
rotationManager.RegisterKey("encryption-key-001", "ML-KEM-768");
// Periodic health check
foreach (var keyId in new[] { "encryption-key-001", "signing-key-002" })
{
var status = rotationManager.CheckRotationStatus(keyId);
switch (status)
{
case KeyRotationStatus.Expired:
Console.Error.WriteLine($"{keyId}: EXPIRED — rotation required immediately.");
break;
case KeyRotationStatus.Deprecated:
Console.WriteLine($"{keyId}: Deprecated — schedule rotation.");
break;
case KeyRotationStatus.Active:
Console.WriteLine($"{keyId}: Active.");
break;
case KeyRotationStatus.Unknown:
Console.WriteLine($"{keyId}: Unknown key ID.");
break;
}
}
API Reference
IKem
| Method | Description |
|---|---|
EncapsulateAsync(PublicKeyRef, CancellationToken) → Task<EncapsulationResult> |
Encapsulates a shared secret to a recipient's public key |
DecapsulateAsync(KeyRef, ReadOnlyMemory<byte>, CancellationToken) → Task<ReadOnlyMemory<byte>> |
Decapsulates a received ciphertext to recover the shared secret |
ISignature
| Method | Description |
|---|---|
SignAsync(KeyRef, Stream, SignOptions, CancellationToken) → Task<SignedArtifact> |
Signs a stream with the specified signing key and options |
VerifyAsync(Stream, SignedArtifact, CancellationToken) → Task<VerificationResult> |
Verifies a signed artifact against the content stream |
ISymmetric
| Method | Description |
|---|---|
ValidatePolicy(string, CryptoParameters) → SymmetricPolicyResult |
Checks algorithm/key-size against configured minimum |
GetMinimumKeySize(string) → int |
Returns the configured minimum key size |
IProviderRegistry
| Method | Description |
|---|---|
Register(IKemProvider) |
Register a KEM provider by algorithm name |
Register(ISignatureProvider) |
Register a signature provider by algorithm name |
ResolveKem(string) → IKemProvider |
Resolve KEM provider (throws if not found) |
ResolveSignature(string) → ISignatureProvider |
Resolve signature provider (throws if not found) |
TryResolveKem(string, out IKemProvider?) → bool |
Non-throwing resolution |
TryResolveSignature(string, out ISignatureProvider?) → bool |
Non-throwing resolution |
IKeyStore
| Method | Description |
|---|---|
GetKeyAsync(string, CancellationToken) → Task<KeyRef> |
Retrieves a private key by ID |
GetPublicKeyAsync(string, CancellationToken) → Task<PublicKeyRef> |
Retrieves a public key by ID |
ICryptoEventSource
| Method | Description |
|---|---|
Emit(CryptoEvent) |
Emits a diagnostic crypto event |
KeyRotationManager
| Method | Description |
|---|---|
RegisterKey(string, string, int?) → KeyMetadata |
Registers a key and returns its metadata |
CheckRotationStatus(string) → KeyRotationStatus |
Returns active/deprecated/expired/unknown |
GetMetadata(string) → KeyMetadata? |
Returns key metadata if registered |
SecureMemory
| Method | Description |
|---|---|
Clear(byte[]) |
Zeros a byte array in place |
Clear(Span<byte>) |
Zeros a span in place |
CopyAndClear(byte[]) → byte[] |
Returns a copy and zeros the source |
Core Types
| Type | Description |
|---|---|
PublicKeyRef |
Record: KeyId, Algorithm? — identifies a recipient public key |
KeyRef |
Record: KeyId, Algorithm? — identifies a private key |
EncapsulationResult |
Record: Ciphertext (ReadOnlyMemory), SharedSecret (ReadOnlyMemory) |
SignOptions |
Record: Mode (CryptoMode), SchemeId? |
ProviderInfo |
Record: Name, IsExperimental, Validation |
KeyRotationPolicy |
Record: MaximumKeyLifetime, DeprecationWindow, RequireRotationBeforeExpiry |
KeyMetadata |
Record: KeyId, CreatedAt, ExpiresAt, DeprecatedAt, IsExpired, IsDeprecated, Algorithm, KeySize? |
KeyRotationStatus |
Enum: Active, Deprecated, Expired, Unknown |
SymmetricPolicyResult |
Value struct: IsCompliant, Reason? |
CryptoConfig |
Record: KemProviders, SignatureProviders, RequireValidatedProviders, DefaultKem, DefaultSignature |
CryptoConfigEntry |
Record: Algorithm, ProviderType, Pinnable, Pinned, MinimumValidation |
Configuration Options
CryptoConfig
All configuration is centralized in CryptoConfig:
var config = new CryptoConfig(
KemProviders: new[]
{
new CryptoConfigEntry(
Algorithm: "ML-KEM-768",
ProviderType: "BouncyCastle",
Pinnable: true,
Pinned: false,
MinimumValidation: ValidationStatus.Validated),
},
SignatureProviders: new[]
{
new CryptoConfigEntry("ML-DSA-65", "BouncyCastle",
Pinnable: true, Pinned: false,
MinimumValidation: ValidationStatus.Validated),
},
RequireValidatedProviders: false, // Allow experimental providers in dev
DefaultKem: "ML-KEM-768",
DefaultSignature: "ML-DSA-65");
| Config Field | Type | Default | Description |
|---|---|---|---|
KemProviders |
IReadOnlyList<CryptoConfigEntry> |
— | Per-algorithm KEM provider configs |
SignatureProviders |
IReadOnlyList<CryptoConfigEntry> |
— | Per-algorithm signature provider configs |
RequireValidatedProviders |
bool |
false |
If true, only Validated providers can be used |
DefaultKem |
string? |
"ML-KEM-768" |
Default KEM algorithm when not specified |
DefaultSignature |
string? |
"ML-DSA-65" |
Default signature algorithm when not specified |
Per-Algorithm Config (CryptoConfigEntry)
| Field | Type | Description |
|---|---|---|
Algorithm |
string |
Algorithm name (e.g., "ML-KEM-768") |
ProviderType |
string |
Provider identifier (e.g., "Native", "BouncyCastle", "HSM") |
Pinnable |
bool |
Whether this algorithm/provider pair is suitable for pinning |
Pinned |
bool |
Whether this provider is the pinned choice for this algorithm |
MinimumValidation |
ValidationStatus |
Minimum required validation level |
Symmetric Policy
| Parameter | Type | Default | Description |
|---|---|---|---|
minimumKeySize |
int |
256 |
Minimum bit-length for symmetric keys |
Key Rotation Policy
| Field | Type | Description |
|---|---|---|
MaximumKeyLifetime |
TimeSpan |
Total lifetime before expiry |
DeprecationWindow |
TimeSpan |
Period before expiry where key is deprecated (warning) |
RequireRotationBeforeExpiry |
bool |
Whether rotation must occur before the key expires |
CompositeSignature Requirements
For hybrid mode verification to succeed:
- The signed artifact's
Header.Modemust beCryptoMode.Hybrid - The
Header.SchemeIdmust contain at least 2 components separated by+ - Every component must resolve to a registered
ISignatureProvider - Every component must verify successfully (fail-closed behavior)
Generated for CipherShift365 Vault SDK. Part of the CipherShift365 PQC Readiness Platform.