- Created `StellaOps.TestKit.Tests` project for unit tests related to determinism. - Implemented `DeterminismManifestTests` to validate deterministic output for canonical bytes and strings, file read/write operations, and error handling for invalid schema versions. - Added `SbomDeterminismTests` to ensure identical inputs produce consistent SBOMs across SPDX 3.0.1 and CycloneDX 1.6/1.7 formats, including parallel execution tests. - Updated project references in `StellaOps.Integration.Determinism` to include the new determinism testing library.
599 lines
21 KiB
Markdown
599 lines
21 KiB
Markdown
# Offline Verification Crypto Provider - Security Guide
|
|
|
|
**Document Version**: 1.0
|
|
**Last Updated**: 2025-12-23
|
|
**Status**: Active
|
|
**Audience**: Security Engineers, Platform Operators, DevOps Teams
|
|
**Sprint**: SPRINT_1000_0007_0002
|
|
|
|
## Table of Contents
|
|
|
|
1. [Overview](#overview)
|
|
2. [Architecture](#architecture)
|
|
3. [Security Model](#security-model)
|
|
4. [Algorithm Support](#algorithm-support)
|
|
5. [Deployment Scenarios](#deployment-scenarios)
|
|
6. [API Reference](#api-reference)
|
|
7. [Trust Establishment](#trust-establishment)
|
|
8. [Threat Model](#threat-model)
|
|
9. [Compliance](#compliance)
|
|
10. [Best Practices](#best-practices)
|
|
11. [Troubleshooting](#troubleshooting)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The **OfflineVerificationCryptoProvider** is a cryptographic abstraction layer that wraps .NET BCL (`System.Security.Cryptography`) to enable **configuration-driven cryptography** in offline, air-gapped, and sovereignty-constrained environments.
|
|
|
|
### Purpose
|
|
|
|
- **Offline Operations**: Function without network access to external cryptographic services
|
|
- **Deterministic Behavior**: Reproducible signatures and hashes for compliance auditing
|
|
- **Zero External Dependencies**: No cloud KMS, HSMs, or online certificate authorities required
|
|
- **Regional Neutrality**: NIST-approved algorithms without regional compliance constraints
|
|
|
|
### Key Features
|
|
|
|
- ECDSA (ES256/384/512) and RSA (RS256/384/512, PS256/384/512) signing/verification
|
|
- SHA-2 family hashing (SHA-256/384/512)
|
|
- Ephemeral verification for public-key-only scenarios (DSSE, JWT, JWS)
|
|
- Configuration-driven plugin architecture with priority-based selection
|
|
- Zero-cost abstraction over .NET BCL primitives
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### Component Hierarchy
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Production Code (AirGap, Scanner, Attestor) │
|
|
│ ├── Uses: ICryptoProvider abstraction │
|
|
│ └── Never touches: System.Security.Cryptography │
|
|
└─────────────────────────────────────────────────────────┘
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ StellaOps.Cryptography (Core Abstraction) │
|
|
│ ├── ICryptoProvider interface │
|
|
│ ├── ICryptoSigner interface │
|
|
│ ├── ICryptoHasher interface │
|
|
│ └── CryptoProviderRegistry │
|
|
└─────────────────────────────────────────────────────────┘
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ OfflineVerificationCryptoProvider (Plugin) │
|
|
│ ├── BclHasher (SHA-256/384/512) │
|
|
│ ├── EcdsaSigner (ES256/384/512) │
|
|
│ ├── RsaSigner (RS/PS 256/384/512) │
|
|
│ ├── EcdsaEphemeralVerifier (public-key-only) │
|
|
│ └── RsaEphemeralVerifier (public-key-only) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ System.Security.Cryptography (.NET BCL) │
|
|
│ ├── ECDsa (NIST P-256/384/521) │
|
|
│ ├── RSA (2048/3072/4096-bit) │
|
|
│ └── SHA256/SHA384/SHA512 │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Isolation Boundaries
|
|
|
|
**Crypto Operations Allowed**:
|
|
- ✅ Inside `StellaOps.Cryptography.Plugin.*` projects
|
|
- ✅ Inside unit test projects (`__Tests/**`)
|
|
- ❌ **NEVER** in production application code
|
|
|
|
**Enforcement Mechanisms**:
|
|
1. **Static Analysis**: `scripts/audit-crypto-usage.ps1`
|
|
2. **CI Validation**: `.gitea/workflows/crypto-compliance.yml`
|
|
3. **Code Review**: Automated checks on pull requests
|
|
|
|
---
|
|
|
|
## Security Model
|
|
|
|
### Threat Categories
|
|
|
|
| Threat | Likelihood | Impact | Mitigation |
|
|
|--------|------------|--------|------------|
|
|
| **Key Extraction** | Medium | High | In-memory keys only, minimize key lifetime |
|
|
| **Side-Channel (Timing)** | Low | Medium | .NET BCL uses constant-time primitives |
|
|
| **Algorithm Downgrade** | Very Low | Critical | Compile-time algorithm allowlist |
|
|
| **Public Key Substitution** | Medium | Critical | Fingerprint verification, out-of-band trust |
|
|
| **Replay Attack** | Medium | Medium | Include timestamps in signed payloads |
|
|
| **Man-in-the-Middle** | Low (offline) | N/A | Physical media transport |
|
|
|
|
### Trust Boundaries
|
|
|
|
```
|
|
┌────────────────────────────────────────────────────────┐
|
|
│ Trusted Computing Base (TCB) │
|
|
│ ├── .NET Runtime (Microsoft-signed) │
|
|
│ ├── OfflineVerificationCryptoProvider (AGPL-3.0) │
|
|
│ └── Pre-distributed Public Key Fingerprints │
|
|
└────────────────────────────────────────────────────────┘
|
|
▲
|
|
│ Trust Anchor
|
|
│
|
|
┌────────────────────────────────────────────────────────┐
|
|
│ Untrusted Zone │
|
|
│ ├── Container Images (to be verified) │
|
|
│ ├── SBOMs (to be verified) │
|
|
│ └── VEX Documents (to be verified) │
|
|
└────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**Trust Establishment**:
|
|
1. **Pre-distribution**: Public key fingerprints embedded in airgap bundle
|
|
2. **Out-of-Band Verification**: Manual verification via secure channel
|
|
3. **Chain of Trust**: Each signature verified against trusted fingerprints
|
|
|
|
---
|
|
|
|
## Algorithm Support
|
|
|
|
### Signing & Verification
|
|
|
|
| Algorithm | Curve/Key Size | Hash | Padding | Use Case |
|
|
|-----------|----------------|------|---------|----------|
|
|
| **ES256** | NIST P-256 | SHA-256 | N/A | DSSE envelopes, in-toto attestations |
|
|
| **ES384** | NIST P-384 | SHA-384 | N/A | High-security SBOM signatures |
|
|
| **ES512** | NIST P-521 | SHA-512 | N/A | Long-term archival signatures |
|
|
| **RS256** | 2048+ bits | SHA-256 | PKCS1 | Legacy compatibility |
|
|
| **RS384** | 2048+ bits | SHA-384 | PKCS1 | Legacy compatibility |
|
|
| **RS512** | 2048+ bits | SHA-512 | PKCS1 | Legacy compatibility |
|
|
| **PS256** | 2048+ bits | SHA-256 | PSS | Recommended RSA (FIPS 186-4) |
|
|
| **PS384** | 2048+ bits | SHA-384 | PSS | Recommended RSA (FIPS 186-4) |
|
|
| **PS512** | 2048+ bits | SHA-512 | PSS | Recommended RSA (FIPS 186-4) |
|
|
|
|
### Content Hashing
|
|
|
|
| Algorithm | Output Size | Performance | Use Case |
|
|
|-----------|-------------|-------------|----------|
|
|
| **SHA-256** | 256 bits | Fast | Default for most use cases |
|
|
| **SHA-384** | 384 bits | Medium | Medium-security requirements |
|
|
| **SHA-512** | 512 bits | Medium | High-security requirements |
|
|
|
|
**Normalization**: Both `SHA-256` and `SHA256` formats accepted, normalized to `SHA-256`.
|
|
|
|
### Password Hashing
|
|
|
|
**Not Supported.** Use dedicated password hashers:
|
|
- `Argon2idPasswordHasher` for modern password hashing
|
|
- `Pbkdf2PasswordHasher` for legacy compatibility
|
|
|
|
---
|
|
|
|
## Deployment Scenarios
|
|
|
|
### Scenario 1: Air-Gapped Container Scanning
|
|
|
|
**Environment**: Offline network segment, no internet access
|
|
|
|
**Configuration**:
|
|
```json
|
|
{
|
|
"cryptoProvider": "offline-verification",
|
|
"algorithms": {
|
|
"signing": "ES256",
|
|
"hashing": "SHA-256"
|
|
},
|
|
"trustRoots": {
|
|
"fingerprints": [
|
|
"sha256:a1b2c3d4e5f6....",
|
|
"sha256:f6e5d4c3b2a1...."
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Trust Establishment**:
|
|
1. Pre-distribute trust bundle via USB/DVD: `offline-kit.tar.gz`
|
|
2. Bundle contains:
|
|
- Public key fingerprints (`trust-anchors.json`)
|
|
- Root CA certificates (if applicable)
|
|
- Offline crypto provider plugin
|
|
3. Operator verifies bundle signature using out-of-band channel
|
|
|
|
**Workflow**:
|
|
```
|
|
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
│ Scan │──▶│ Generate │──▶│ Sign │──▶│ Verify │
|
|
│ Container│ │ SBOM │ │ with ES256│ │ Signature│
|
|
└──────────┘ └──────────┘ └──────────┘ └──────────┘
|
|
│ │
|
|
▼ ▼
|
|
OfflineVerificationCryptoProvider
|
|
```
|
|
|
|
### Scenario 2: Sovereign Cloud Deployment
|
|
|
|
**Environment**: National cloud with data residency requirements
|
|
|
|
**Configuration**:
|
|
```json
|
|
{
|
|
"cryptoProvider": "offline-verification",
|
|
"jurisdiction": "world",
|
|
"compliance": ["NIST", "offline-airgap"],
|
|
"keyRotation": {
|
|
"enabled": true,
|
|
"intervalDays": 90
|
|
}
|
|
}
|
|
```
|
|
|
|
**Key Considerations**:
|
|
- Keys generated and stored within sovereign boundary
|
|
- No external KMS dependencies
|
|
- Audit trail for all cryptographic operations
|
|
- Compliance with local data protection laws
|
|
|
|
### Scenario 3: CI/CD Pipeline with Reproducible Builds
|
|
|
|
**Environment**: Build server with deterministic signing
|
|
|
|
**Configuration**:
|
|
```json
|
|
{
|
|
"cryptoProvider": "offline-verification",
|
|
"deterministicSigning": true,
|
|
"algorithms": {
|
|
"signing": "ES256",
|
|
"hashing": "SHA-256"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Workflow**:
|
|
1. Build produces identical artifact hash
|
|
2. Offline provider signs with deterministic ECDSA (RFC 6979)
|
|
3. CI stores signature alongside artifact
|
|
4. Downstream consumers verify signature before deployment
|
|
|
|
---
|
|
|
|
## API Reference
|
|
|
|
### ICryptoProvider.CreateEphemeralVerifier (New in v1.0)
|
|
|
|
**Signature**:
|
|
```csharp
|
|
ICryptoSigner CreateEphemeralVerifier(
|
|
string algorithmId,
|
|
ReadOnlySpan<byte> publicKeyBytes)
|
|
```
|
|
|
|
**Purpose**: Create a verification-only signer from raw public key bytes, without key persistence or management overhead.
|
|
|
|
**Parameters**:
|
|
- `algorithmId`: Algorithm identifier (ES256, RS256, PS256, etc.)
|
|
- `publicKeyBytes`: Public key in **SubjectPublicKeyInfo** (SPKI) format, DER-encoded
|
|
|
|
**Returns**: `ICryptoSigner` instance with:
|
|
- `VerifyAsync(data, signature)` - Returns `true` if signature valid
|
|
- `SignAsync(data)` - Throws `NotSupportedException`
|
|
- `KeyId` - Returns `"ephemeral"`
|
|
- `AlgorithmId` - Returns the specified algorithm
|
|
|
|
**Throws**:
|
|
- `NotSupportedException`: Algorithm not supported or public key format invalid
|
|
- `CryptographicException`: Public key parsing failed
|
|
|
|
**Usage Example**:
|
|
```csharp
|
|
// DSSE envelope verification
|
|
var envelope = DsseEnvelope.Parse(envelopeJson);
|
|
var trustRoots = LoadTrustRoots();
|
|
|
|
foreach (var signature in envelope.Signatures)
|
|
{
|
|
// Get public key from trust store
|
|
if (!trustRoots.PublicKeys.TryGetValue(signature.KeyId, out var publicKeyBytes))
|
|
continue;
|
|
|
|
// Verify fingerprint
|
|
var fingerprint = ComputeFingerprint(publicKeyBytes);
|
|
if (!trustRoots.TrustedFingerprints.Contains(fingerprint))
|
|
continue;
|
|
|
|
// Create ephemeral verifier
|
|
var verifier = cryptoProvider.CreateEphemeralVerifier("PS256", publicKeyBytes);
|
|
|
|
// Build pre-authentication encoding (PAE)
|
|
var pae = BuildPAE(envelope.PayloadType, envelope.Payload);
|
|
|
|
// Verify signature
|
|
var isValid = await verifier.VerifyAsync(pae, Convert.FromBase64String(signature.Signature));
|
|
|
|
if (isValid)
|
|
return ValidationResult.Success();
|
|
}
|
|
|
|
return ValidationResult.Failure("No valid signature found");
|
|
```
|
|
|
|
### ICryptoHasher.ComputeHash
|
|
|
|
**Signature**:
|
|
```csharp
|
|
byte[] ComputeHash(ReadOnlySpan<byte> data)
|
|
```
|
|
|
|
**Usage Example**:
|
|
```csharp
|
|
var hasher = cryptoProvider.GetHasher("SHA-256");
|
|
var hash = hasher.ComputeHash(fileBytes);
|
|
var hex = Convert.ToHexString(hash).ToLowerInvariant();
|
|
```
|
|
|
|
### ICryptoSigner.SignAsync / VerifyAsync
|
|
|
|
**Signatures**:
|
|
```csharp
|
|
ValueTask<byte[]> SignAsync(ReadOnlyMemory<byte> data, CancellationToken ct = default)
|
|
ValueTask<bool> VerifyAsync(ReadOnlyMemory<byte> data, ReadOnlyMemory<byte> signature, CancellationToken ct = default)
|
|
```
|
|
|
|
**Usage Example**:
|
|
```csharp
|
|
// Signing
|
|
var signingKey = new CryptoSigningKey(
|
|
reference: new CryptoKeyReference("my-key"),
|
|
algorithmId: "ES256",
|
|
privateParameters: ecParameters,
|
|
createdAt: DateTimeOffset.UtcNow);
|
|
|
|
cryptoProvider.UpsertSigningKey(signingKey);
|
|
var signer = cryptoProvider.GetSigner("ES256", new CryptoKeyReference("my-key"));
|
|
var signature = await signer.SignAsync(data);
|
|
|
|
// Verification
|
|
var isValid = await signer.VerifyAsync(data, signature);
|
|
```
|
|
|
|
---
|
|
|
|
## Trust Establishment
|
|
|
|
### Offline Trust Bundle Structure
|
|
|
|
```
|
|
offline-kit.tar.gz
|
|
├── trust-anchors.json # Public key fingerprints
|
|
├── public-keys/ # Public keys in SPKI format
|
|
│ ├── scanner-key-001.pub
|
|
│ ├── scanner-key-002.pub
|
|
│ └── attestor-key-001.pub
|
|
├── metadata/
|
|
│ ├── bundle-manifest.json # Bundle metadata
|
|
│ └── bundle-signature.sig # Bundle self-signature
|
|
└── crypto-plugins/
|
|
└── StellaOps.Cryptography.Plugin.OfflineVerification.dll
|
|
```
|
|
|
|
### trust-anchors.json Format
|
|
|
|
```json
|
|
{
|
|
"version": "1.0",
|
|
"createdAt": "2025-12-23T00:00:00Z",
|
|
"expiresAt": "2026-12-23T00:00:00Z",
|
|
"trustAnchors": [
|
|
{
|
|
"keyId": "scanner-key-001",
|
|
"algorithmId": "ES256",
|
|
"fingerprint": "sha256:a1b2c3d4e5f6...",
|
|
"purpose": "container-scanning",
|
|
"notBefore": "2025-01-01T00:00:00Z",
|
|
"notAfter": "2026-01-01T00:00:00Z"
|
|
}
|
|
],
|
|
"bundleSignature": {
|
|
"keyId": "bundle-signing-key",
|
|
"algorithmId": "ES256",
|
|
"signature": "base64encodedSignature=="
|
|
}
|
|
}
|
|
```
|
|
|
|
### Fingerprint Computation
|
|
|
|
```csharp
|
|
private string ComputeFingerprint(byte[] publicKeyBytes)
|
|
{
|
|
var hasher = cryptoProvider.GetHasher("SHA-256");
|
|
var hash = hasher.ComputeHash(publicKeyBytes);
|
|
return "sha256:" + Convert.ToHexString(hash).ToLowerInvariant();
|
|
}
|
|
```
|
|
|
|
### Out-of-Band Verification Process
|
|
|
|
1. **Bundle Reception**: Operator receives `offline-kit.tar.gz` via physical media
|
|
2. **Checksum Verification**: Compare SHA-256 hash against value published via secure channel
|
|
```bash
|
|
sha256sum offline-kit.tar.gz
|
|
# Compare with published value: a1b2c3d4e5f6...
|
|
```
|
|
3. **Bundle Signature Verification**: Extract bundle, verify self-signature using bootstrap public key
|
|
4. **Trust Anchor Review**: Manual review of trust-anchors.json entries
|
|
5. **Deployment**: Extract crypto plugin and trust anchors to deployment directory
|
|
|
|
---
|
|
|
|
## Threat Model
|
|
|
|
### Attack Surface Analysis
|
|
|
|
| Attack Vector | Likelihood | Impact | Mitigation |
|
|
|---------------|------------|--------|------------|
|
|
| **Memory Dump** | Medium | High | Use ephemeral keys, minimize key lifetime |
|
|
| **Side-Channel (Timing)** | Low | Medium | .NET BCL uses constant-time primitives |
|
|
| **Algorithm Substitution** | Very Low | Critical | Compile-time algorithm allowlist |
|
|
| **Public Key Substitution** | Medium | Critical | Fingerprint verification, out-of-band trust |
|
|
| **Replay Attack** | Medium | Medium | Include timestamps in signed payloads |
|
|
| **Man-in-the-Middle** | Low (offline) | N/A | Physical media transport |
|
|
|
|
### Mitigations by Threat
|
|
|
|
**T1: Private Key Extraction**
|
|
- **Control**: In-memory keys only, no disk persistence
|
|
- **Monitoring**: Log key usage events
|
|
- **Response**: Revoke compromised key, rotate to new key
|
|
|
|
**T2: Public Key Substitution**
|
|
- **Control**: SHA-256 fingerprint verification before use
|
|
- **Monitoring**: Alert on fingerprint mismatches
|
|
- **Response**: Investigate trust bundle integrity
|
|
|
|
**T3: Signature Replay**
|
|
- **Control**: Include timestamp and nonce in signed payloads
|
|
- **Monitoring**: Detect signatures older than TTL
|
|
- **Response**: Reject replayed signatures
|
|
|
|
**T4: Algorithm Downgrade**
|
|
- **Control**: Hardcoded algorithm allowlist in provider
|
|
- **Monitoring**: Log algorithm selection
|
|
- **Response**: Reject unsupported algorithms
|
|
|
|
---
|
|
|
|
## Compliance
|
|
|
|
### NIST Standards
|
|
|
|
| Standard | Requirement | Compliance |
|
|
|----------|-------------|------------|
|
|
| **FIPS 186-4** | Digital Signature Standard | ✅ ECDSA with P-256/384/521, RSA-PSS |
|
|
| **FIPS 180-4** | Secure Hash Standard | ✅ SHA-256/384/512 |
|
|
| **FIPS 140-2** | Cryptographic Module Validation | ⚠️ .NET BCL (software-only, not validated) |
|
|
|
|
**Notes**:
|
|
- For FIPS 140-2 Level 3+ compliance, use HSM-backed crypto provider
|
|
- Software-only crypto acceptable for FIPS 140-2 Level 1
|
|
|
|
### RFC Standards
|
|
|
|
| RFC | Title | Compliance |
|
|
|-----|-------|------------|
|
|
| **RFC 8017** | PKCS #1: RSA Cryptography v2.2 | ✅ RSASSA-PKCS1-v1_5, RSASSA-PSS |
|
|
| **RFC 6979** | Deterministic DSA/ECDSA | ✅ Via BouncyCastle fallback (optional) |
|
|
| **RFC 5280** | X.509 Public Key Infrastructure | ✅ SubjectPublicKeyInfo format |
|
|
| **RFC 7515** | JSON Web Signature (JWS) | ✅ ES256/384/512, RS256/384/512, PS256/384/512 |
|
|
|
|
### Regional Standards
|
|
|
|
| Region | Standard | Compliance |
|
|
|--------|----------|------------|
|
|
| **European Union** | eIDAS Regulation (EU) 910/2014 | ❌ Use eIDAS plugin |
|
|
| **Russia** | GOST R 34.10-2012 | ❌ Use CryptoPro plugin |
|
|
| **China** | SM2/SM3/SM4 (GM/T 0003-2012) | ❌ Use SM crypto plugin |
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### Key Management
|
|
|
|
**✅ DO**:
|
|
- Rotate signing keys every 90 days
|
|
- Use separate keys for different purposes
|
|
- Store private keys in memory only
|
|
- Use ephemeral verifiers for public-key-only scenarios
|
|
- Audit all key usage events
|
|
|
|
**❌ DON'T**:
|
|
- Reuse keys across environments
|
|
- Store keys in configuration files
|
|
- Use RSA keys smaller than 2048 bits
|
|
- Use SHA-1 or MD5
|
|
- Bypass fingerprint verification
|
|
|
|
### Algorithm Selection
|
|
|
|
**Recommended**:
|
|
1. **ES256** (ECDSA P-256/SHA-256) - Best balance
|
|
2. **PS256** (RSA-PSS 2048-bit/SHA-256) - For RSA-required scenarios
|
|
3. **SHA-256** - Default hashing algorithm
|
|
|
|
**Avoid**:
|
|
- ES512 / PS512 - Performance overhead
|
|
- RS256 / RS384 / RS512 - Legacy PKCS1 padding
|
|
|
|
### Performance Optimization
|
|
|
|
**Caching**:
|
|
```csharp
|
|
// Cache hashers (thread-safe, reusable)
|
|
private readonly ICryptoHasher _sha256Hasher;
|
|
|
|
public MyService(ICryptoProviderRegistry registry)
|
|
{
|
|
_sha256Hasher = registry.ResolveHasher("SHA-256").Hasher;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Issue**: `NotSupportedException: Algorithm 'RS256' is not supported`
|
|
|
|
**Resolution**:
|
|
- Verify algorithm ID is exactly `RS256` (case-sensitive)
|
|
- Check provider supports: `provider.Supports(CryptoCapability.Signing, "RS256")`
|
|
|
|
---
|
|
|
|
**Issue**: `CryptographicException: Public key parsing failed`
|
|
|
|
**Resolution**:
|
|
- Ensure public key is DER-encoded SPKI format
|
|
- Convert from PEM: `openssl x509 -pubkey -noout -in cert.pem | openssl enc -base64 -d > pubkey.der`
|
|
|
|
---
|
|
|
|
**Issue**: Signature verification always returns `false`
|
|
|
|
**Resolution**:
|
|
1. Verify algorithm matches
|
|
2. Ensure message is identical (byte-for-byte)
|
|
3. Check public key matches private key
|
|
4. Enable debug logging
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
### Related Documentation
|
|
|
|
- [Crypto Architecture Overview](../modules/platform/crypto-architecture.md)
|
|
- [ICryptoProvider Interface](../../src/__Libraries/StellaOps.Cryptography/CryptoProvider.cs)
|
|
- [Plugin Manifest Schema](../../etc/crypto-plugins-manifest.json)
|
|
- [AirGap Module Architecture](../modules/airgap/architecture.md)
|
|
- [Sprint Documentation](../implplan/SPRINT_1000_0007_0002_crypto_refactoring.md)
|
|
|
|
### External Standards
|
|
|
|
- [NIST FIPS 186-4: Digital Signature Standard](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf)
|
|
- [NIST FIPS 180-4: Secure Hash Standard](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf)
|
|
- [RFC 8017: PKCS #1 v2.2](https://www.rfc-editor.org/rfc/rfc8017)
|
|
- [RFC 6979: Deterministic ECDSA](https://www.rfc-editor.org/rfc/rfc6979)
|
|
- [RFC 7515: JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515)
|
|
|
|
---
|
|
|
|
**Document Control**
|
|
|
|
| Version | Date | Author | Changes |
|
|
|---------|------|--------|---------|
|
|
| 1.0 | 2025-12-23 | StellaOps Platform Team | Initial release with CreateEphemeralVerifier API |
|
|
|
|
**License**: AGPL-3.0-or-later
|