mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-16 21:02:51 +08:00
d552634258
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>
6.9 KiB
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
- Endpoints and message security
- Users and permissions
- Secrets and private keys
- Resource limits
- Diagnostics and auditing
- Clients
- Deployment and operation
Application identity and certificates
- Give each installation a unique
ApplicationUrithat matches its application certificate. See Concepts: applications. - Set
PkiRootto 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
AutoAcceptUntrustedCertificatesdisabled, 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
- Offer
SignAndEncryptendpoints and keepIncludeUnsecurePolicyNoneset tofalse; both are the hosted-server defaults. See Server security and resource controls. - Enable
IncludeEccPoliciesonly when every client supports the ECC policies. On .NET Framework only the CBC-based ECC policies are available, and their ECDH agreement runs in BouncyCastle rather than a validated module. See ECC profiles: known limitations. - Configure clients to select a
SignAndEncryptendpoint. See Concepts: endpoints, secure channels, and sessions.
Users and permissions
- Decide whether anonymous access is acceptable. A hosted server without
UserTokenPoliciesadvertises anAnonymouspolicy. 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
ISecretStorethat is backed by a durable, access-controlled secret service; a hosted server registers one withAddSecretStore. 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 serviceOperationLimits. See Operation limits. - Tune the admission rate limits, which are enabled by default, with
ConfigureRateLimits. See Rate limiting. - Review the resource-isolation profile;
Balancedis 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, defaulttrue), 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
- Keep the default reconnect policy for long-running clients. The Getting started client limits retries only to report errors quickly. See Reconnect semantics.
- Trust server certificates explicitly instead of accepting them automatically. See Certificates.
- Store namespace URIs, not namespace indexes, and resolve indexes after each connection. See Concepts: node identity and namespaces.
- Pass cancellation tokens and dispose sessions and subscriptions. See Concepts: how the SDK is organized.
Deployment and operation
- Keep the clocks of clients and servers synchronized, for example with NTP or PTP. Certificate validity, timestamps, and redundancy depend on it. See Kubernetes: time synchronization.
- In containers, mount the certificate stores on persistent storage and supply secrets at run time. See Container reference server and Kubernetes: secrets, certificates, and trust.
- Use a Global Discovery Server or provisioning mode to manage certificates across many installations. See GDS and Provisioning mode.
- Add redundancy only when availability requirements need it. See High availability.