Skip to main content
net10.0.NETFramework4.7.2.NETFramework4.8net8.0net9.0.NETStandard2.1

OPC UA PKCS#11 certificate store and crypto provider class library. Keeps private keys inside a hardware token or HSM.

Published
Jan 1, 1900
128y ago
Total Downloads
0
0

Install

dotnet add package OPCFoundation.NetStandard.Opc.Ua.Security.Pkcs11.Debug --version 2.0.0-preview.2
ProductVersions
.NET
net10.0net8.0net9.0
.NET Standard
netstandard2.1
Other
.NETFramework4.7.2.NETFramework4.8

README

OPC UA .NET Standard — PKCS#11 certificate store

OPCFoundation.NetStandard.Opc.Ua.Security.Pkcs11 lets an OPC UA application keep its private keys inside a hardware token, smart card or HSM. The key is used for signing and decryption but is never present in process memory and can never be exported.

This package is optional. OPCFoundation.NetStandard.Opc.Ua.Core does not reference it, so applications that do not use a token are unaffected.

Getting started

Register the store provider, then point any certificate store at the token with an RFC 7512 pkcs11: URI:

using Microsoft.Extensions.DependencyInjection;

builder.Services.AddOpcUa()
    .AddPkcs11CertificateStore(new Pkcs11TokenOptions
    {
        ModulePath = "/usr/lib/softhsm/libsofthsm2.so",
        TokenLabel = "opcua",
        PinProvider = () => secretStore.Read("token-pin")
    });

Without dependency injection, pass the provider to the certificate manager directly:

ICertificateManager manager = CertificateManagerFactory.Create(
    securityConfiguration,
    telemetry,
    options => options.AddStoreProvider(new Pkcs11StoreProvider()));

A store path names the token, and may carry the module and PIN:

pkcs11:token=opcua;object=server?module-path=/usr/lib/softhsm/libsofthsm2.so&pin-value=1234

Prefer Pkcs11TokenOptions.PinProvider over pin-value so the PIN comes from a secret store rather than a configuration file.

What is supported

Operation Mechanism
RSA signing, PKCS#1 v1.5 CKM_RSA_PKCS with a DER DigestInfo
RSA signing, PSS CKM_RSA_PKCS_PSS with MGF1 and a matching salt length
RSA decryption, OAEP CKM_RSA_PKCS_OAEP
RSA decryption, PKCS#1 v1.5 CKM_RSA_PKCS
ECDSA signing CKM_ECDSA

SHA-256, SHA-384 and SHA-512 are supported. SHA-1 is deliberately not.

Which security policies actually work depends on the mechanisms your token implements, not only on this package. SoftHSM2, for instance, signs happily with PKCS#1 v1.5 and PSS but accepts OAEP only with SHA-1, so it cannot serve the policies that need OAEP with SHA-256.

Limitations

  • Revocation lists are not held on a token. Point the trusted issuer store at a directory store.
  • Objects are provisioned and removed with the token vendor's tools, not through this store.
  • A private key offered to AddAsync is refused and logged: a token does not import key material it did not generate.
  • The token's validation status is reported as uncertified unless you assert one, because nothing in the PKCS#11 interface reports a FIPS certificate. See the crypto provider documentation for how this is audited.

Linux: libdl.so must be present

Pkcs11Interop loads the token module through DllImport("libdl"). glibc 2.34 folded libdl into libc and many distributions now ship only the libdl.so.2 ABI stub, which the .NET loader will not bind the name libdl to. On such a system the first call fails with:

System.DllNotFoundException: Unable to load shared library 'libdl'

Install your distribution's C development package (libc6-dev on Debian and Ubuntu), which provides the libdl.so name, or create the link yourself:

sudo ln -s /usr/lib/x86_64-linux-gnu/libdl.so.2 /usr/lib/x86_64-linux-gnu/libdl.so
sudo ldconfig

This is a property of the interop library, not of this package, and applies to any .NET application that uses Pkcs11Interop.

Target frameworks

net472, net48, netstandard2.1, net8.0, net9.0, net10.0.

NativeAOT

This package is marked IsAotCompatible on net10.0 and is exercised by the Opc.Ua.Aot.Tests project. Despite Pkcs11Interop carrying no trim or AOT annotations of its own, the ILCompiler analysis produces no trim or AOT warnings for the paths this package uses.

The module itself is resolved through native interop at run time, which trimming does not affect. Note that a native library that is genuinely absent fails the same way in an AOT binary as in a JIT one — see the libdl.so note above.

Additional documentation

See the crypto provider documentation for pluggable cryptography, hardware-held private keys, FIPS claim boundaries and the audit surfaces.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

This version is marked prerelease. Validate its API and upgrade path before production use.No SPDX license expression is published. Review the license text and your organisation's policy before redistribution.Compatibility metadata lists 6 target frameworks; confirm the exact target used by your application.The published metadata declares 130 direct dependency entries across framework groups. Inspect the resolved dependency graph for your target framework.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.