Files
UA-.NETStandard/docs/ProductionChecklist.md
T
romanett d552634258 Enable ECC security policies on net48 via a BouncyCastle raw-ECDH polyfill (#4703)
Closes #4510.

## Summary

OPC UA Part 6 feeds the **raw** ECDH shared secret into HKDF. .NET
Framework only exposes `ECDiffieHellman.DeriveKeyMaterial`, which always
hashes it, so the ECC SecureChannel and user-token policies were
unavailable on `net48` (`SecurityPolicies.GetInfo` returned `null`).

This adds a BouncyCastle polyfill for just that primitive:

-
**`Opc.Ua.Security.Certificates/Org.BouncyCastle/EcdhRawAgreement.cs`**
(`net48` only): an internal `DeriveRawSecretAgreement(this
ECDiffieHellman, ECDiffieHellmanPublicKey)` extension using
`ECDHBasicAgreement`. It returns the X coordinate padded to the field
size, exactly like the .NET 8 BCL method. Keys stay CNG keys; ECDSA
signatures and HKDF stay on the platform — only the agreement step is
managed code. The point is validated (on curve, not infinity) and
mismatched curves are rejected.
- Because the extension mirrors the .NET 8 signature,
`Nonce.GenerateSecret` now has one code path on every target.
- `SupportsRawEccSecretAgreement()` is removed; the CBC-based ECC
policies (`ECC_nistP256`, `ECC_nistP384`, `ECC_brainpoolP256r1`,
`ECC_brainpoolP384r1`) are offered on every target (still subject to OS
curve support).
- BouncyCastle was already a `net48` dependency of
`Opc.Ua.Security.Certificates`; no new package. (Only `net48` is
downlevel now — `netstandard2.1`/`net472` from the issue text are no
longer targets.)

**Not in scope:** the `_AesGcm` / `_ChaChaPoly` ECC variants (and PubSub
DTLS) still need .NET 8 because .NET Framework has no AEAD ciphers —
follow-up stacked on this branch.

## Docs

`EccProfiles.md` (Known limitations), `migrate/2.0.x/certificates.md`,
`ProductionChecklist.md`, `Profiles.md`, `WhatsNewIn2.0.md`. Calls out
that on `net48` the agreement step does not run in a FIPS/validated
module.

## Tests (local)

| Suite | Result |
|---|---|
| `Opc.Ua.Core.Tests` full, net48 | 5956 passed, 0 failed |
| `EccInteropTests` net48 vs 1.5.378 peer (net8.0, native raw ECDH) | 26
passed; 28 skipped (AEAD + curve25519/448) — all four CBC curves, both
directions, UserName tokens, token renewal |
| `Opc.Ua.Sessions.Tests` ECC filter, net48 | 52 passed, 0 failed |
| Server `SessionCoverageTests`/`EphemeralNonce*`, Configuration builder
tests, net48 | all pass |
| Nonce/ECC/EncryptedSecret + session tests, net10.0 | all pass |

New tests: symmetric agreement on all four curves; on net48 an oracle
against CNG (`SHA256(raw) == DeriveKeyFromHash`); curve mismatch and
off-curve rejection. Tests that asserted the old net48 limitation were
updated.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:52:44 +02:00

6.9 KiB

Production readiness checklist

The samples and Getting started use shortcuts that are suitable only on a development computer: temporary certificate stores, automatic certificate acceptance, anonymous users, and short reconnect limits. Review this checklist before you deploy a client or server. Each item links to the guide that explains the setting. The checklist does not replace a security review of your deployment.

Contents

Application identity and certificates

  • Give each installation a unique ApplicationUri that matches its application certificate. See Concepts: applications.
  • Set PkiRoot to a persistent, access-controlled directory. The hosted client and server default to a folder in the system temporary directory. See Application identity and certificate defaults.
  • Keep AutoAcceptUntrustedCertificates disabled, and provision the trusted and issuer certificates, or CA-issued certificates, before peers connect. See Certificates.
  • Keep SHA-1 certificates rejected and an RSA key size of at least 2048 bits; both are the defaults. See Server security and resource controls.
  • Plan certificate renewal and trust-list updates, for example with certificate-expiration alarms, push management, or a Global Discovery Server. See Certificate manager and GDS.

Endpoints and message security

Users and permissions

  • Decide whether anonymous access is acceptable. A hosted server without UserTokenPolicies advertises an Anonymous policy. See User token policies.
  • Register an authenticator for each user-token policy that the server advertises, for example with AddDefaultIdentityAuthenticators. A policy without an authenticator does not authenticate users. See Identity providers.
  • Map identities to roles and restrict node permissions. See Role-based user management.
  • Set session and channel ceilings for the expected load, and keep the failed-authentication lockout (MaxFailedAuthenticationAttempts, default 5). See Server security and resource controls.

Secrets and private keys

  • Keep passwords, tokens, and private keys out of source code, configuration files in source control, and container images.
  • Store credentials through an ISecretStore that is backed by a durable, access-controlled secret service; a hosted server registers one with AddSecretStore. See Dependency injection: server feature.
  • Where policy requires it, keep private keys in a TPM, HSM, PKCS#11 token, or key service. See Crypto providers.

Resource limits

  • Review the transport quotas (MaxMessageSize, MaxArrayLength, MaxByteStringLength) and the service OperationLimits. See Operation limits.
  • Tune the admission rate limits, which are enabled by default, with ConfigureRateLimits. See Rate limiting.
  • Review the resource-isolation profile; Balanced is the default. See Server resource isolation.
  • Size the server for the expected sessions, subscriptions, and monitored items. See Server scalability.

Diagnostics and auditing

  • Send logs, metrics, and traces to your monitoring system through the host's logging and ITelemetryContext. See Diagnostics.
  • Enable audit events when you must record security-relevant actions; they are off by default. See Enabling auditing.
  • Decide whether to keep the server diagnostics nodes (DiagnosticsEnabled, default true), which add per-session and per-subscription work. See Enabling diagnostics.
  • Use packet capture and key logs only for troubleshooting. Key logs make captured traffic decryptable. See Diagnostics: security model.

Clients

Deployment and operation