Zum Hauptinhalt springen

InstanceSecretCrypto

Namespace: Meshmakers.Octo.Sdk.Common.Encryption

AES-256-GCM implementation of IInstanceSecretCrypto. Wire format after the enc:v1: sentinel and Base64 decode: nonce(12) ‖ tag(16) ‖ ciphertext(N).

public sealed class InstanceSecretCrypto : IInstanceSecretCrypto

Inheritance Object → InstanceSecretCrypto
Implements IInstanceSecretCrypto

Remarks:

Wire layout deliberately matches the layouts in the AI Adapter's legacy InstanceSecretEncryptionService and the Communication Controller's WorkloadEncryptionService so the M1 cross-service unification round-trips byte-for-byte. See octo-ai-services/docs/concepts/implementation-m1.md §4.1 for the migration context.

AB#5528: envelope parsing uses SecretEnvelope (Runtime.Contracts), the format definition shared with the engine's ISecretAttributeProtector. InstanceSecretCrypto.Encrypt(Byte[], String) still writes enc:v1 (running clusters and their current callers depend on it; the engine's protector reads it with SecretEncryption:LegacyV1Key, which is the same instance_secret_key).

AB#5534 (decryption-oracle hardening): InstanceSecretCrypto.Decrypt(Byte[], String) decrypts enc:v1 only and refuses enc:v2:<kid>: envelopes. Those live only inside Secret attributes and are decrypted by allowlisted callers through ISecretAttributeProtector.Unprotect(RtSecretValue); decrypting an arbitrary enc:v2 string here would let anyone holding a copied envelope have a service decrypt it.

Implementation is stateless and thread-safe; a single instance can be registered as a singleton across the host. The per-service options binder (e.g. AiEncryptionOptions, CommunicationControllerOptions) is responsible for Base64-decoding the configured key to a 32-byte Byte[] before invoking InstanceSecretCrypto.Encrypt(Byte[], String).

Constructors​

InstanceSecretCrypto()​

Creates an instance that reads and writes enc:v1.

public InstanceSecretCrypto()

InstanceSecretCrypto(ISecretAttributeProtector)​

Kept for compatibility: hosts that register the runtime engine (AddRuntimeEngine()) resolve this constructor through dependency injection. Behaves exactly like the parameterless constructor; the protector is not used, in particular not to decrypt enc:v2 envelopes (AB#5534).

public InstanceSecretCrypto(ISecretAttributeProtector protector)

Parameters​

protector ISecretAttributeProtector
The engine's secret protector; kept for compatibility, not used.

Methods​

Encrypt(Byte[], String)​

public string Encrypt(Byte[] key, string plaintext)

Parameters​

key Byte[]

plaintext String

Returns​

String

Decrypt(Byte[], String)​

public string Decrypt(Byte[] key, string ciphertext)

Parameters​

key Byte[]

ciphertext String

Returns​

String

Remarks:

No enc: prefix: returned unchanged (mixed plaintext/ciphertext during rollouts).

enc:v1:: decrypted with key; a malformed or truncated payload throws CryptographicException.

enc:v2:<kid>:: refused with InvalidOperationException, never decrypted (AB#5534); the message does not contain the value. Secret attribute values are read through ISecretAttributeProtector.

Any other enc: prefix: CryptographicException (unsupported sentinel).

IsEncrypted(String)​

public bool IsEncrypted(string value)

Parameters​

value String

Returns​

Boolean