Authenticating with OPC UA user certificate in QuickOPC

From OPC Labs Knowledge Base


This article describes the code and other steps needed to develop a client with QuickOPC that uses a user certificate to authenticate the use to the OPC UA server.

Basics

The concepts related to user authentication in OPC UA, including the use of X.509 certificate token as one of the alternatives here, are explained in the documentation: OPC UA User Authentication (Client).

Files associated with this article are available at the bottom of the page, zipped.

Creating the user certificate

In most cases, the infrastructure for creating and managing the user certificates will be a "given" and already in place; you will then simply take over the existing certificates.

Using OpenSSL command-line tool

For demonstration purposes, we can create a self-signed user certificate ourselves. We have done this on Windows with OpenSSL command-line tool, using the build of "Win64 OpenSSL v3.6.0" from https://slproweb.com/products/Win32OpenSSL.html . After installing it, we have created a file named CreateUserCertificate.cmd with following content:

set openssl="C:\Program Files\OpenSSL-Win64\bin\openssl.exe"

%openssl% genrsa -out user_private_key.pem 2048
%openssl% req -x509 -new -nodes -key user_private_key.pem -days 365 -out user_certificate.pem -subj "/C=US/O=MyCompany/CN=John Doe" 
%openssl% x509 -in user_certificate.pem -outform der -out user_certificate.der
%openssl% pkcs12 -export -keypbe NONE -certpbe NONE -nomaciter -passout pass: -out user_certificate.pfx -inkey user_private_key.pem -in user_certificate.pem -name "John Doe"

The batch file first creates a new (public and) private key in the user_private_key.pem file. It then creates a user certificate and stores into the user_certificate.pem. Since the certificate might be needed in various forms, it then converts the certificate into user_certificate.pem (private key) and user_certificate.der files, and in the last statement to a user_certificate.pfx file which contains the certificate together with its private key.

User certificate in OPC UA client

Client code with QuickOPC

The code below connects to an OPC UA server, authenticating the user with a certificate from a given file. The endpoint URL, and the node ID used, are for the Prosys OPC UA Simulation Server, but they can be changed as needed to make the example work with other servers.

When successful, the example reads a node and displays its current data value. In case of an error, it displays the corresponding error message.

using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.Extensions;
using OpcLabs.EasyOpc.UA.OperationModel;

var endpointDescriptor = new UAEndpointDescriptor("opc.tcp://localhost:53530/OPCUA/SimulationServer")
    .WithX509CertificateIdentity("user_certificate.pfx");

var client = new EasyUAClient();
try
{
    var attributeData = client.Read(
        endpointDescriptor, 
        "nsu=http://www.prosysopc.com/OPCUA/SimulationNodes/;i=1001");
    Console.WriteLine(attributeData);
}
catch (UAException uaException)
{
    Console.WriteLine($"*** {uaException.InnerException.Message}");
}
Console.ReadLine();

The example uses the user_certificate.pfx file, generated with the procedure described above, for the user certificate. The file must be present in the same directory where the program executable runs. If the certificate cannot be found, you will receive an error similar to this:

Error OpcLabs.UAEngine=1: UA SDK error (OpcLabs.{14DB430B}) in 'static Session.Create'. The certificate query could not create an X.509v3 certificate from the specified PKCS7 signed file "user_certificate.pfx".

The inner exception will be System.Security.Cryptography.CryptographicException with message

The system cannot find the file specified.

In production, certificates residing in files should be appropriately protected. Available methods include setting proper file access permissions, and using a password. QuickOPC supports password-protected certificates too.

Certificates can also reside elsewhere, e.g. in platform-defined stores, which also usually serve for accessing certificates stored on hardware tokens (e.g. USB). Selecting such certificates is achieved with the use of certificate queries.

OpcCmd utility

The following command in the OpcCmd utility does practically the same thing as the code with QuickOPC listed above.

uaClient read opc.tcp://localhost:53530/OPCUA/SimulationServer nsu=http://www.prosysopc.com/OPCUA/SimulationNodes/;i=1001 --EndpointUserCertificateFileName user_certificate.pfx

You can use a full path to the certificate PFX file, if the file is not in the directory where the OpcCmd utility executable is located.

UaExpert

You can use UaExpert to verify whether the OPC UA server is configured properly, and the user certificate works as intended.

In the "Authentication Settings" control group shown when connecting to the server or configuring the connection properties, select the radio box next to Certificate. For Certificate, select the user_certificate.der file. For Private Key, select the user_certificate.pem file.

Configuring the OPC UA server

Prosys OPC UA Simulation Server

We have tested with Prosys OPC UA Simulation Server version 5.6.0-6, on Windows.

The certificate store for user certificates is located under C:\Users\username\.prosysopc\prosys-opc-ua-simulation-server\USERS_PKI\CA .

Steps to do:

  1. Menu: perform Options -> Switch to Expert Mode
  2. On Users tab: In User Authentication Methods, uncheck Anonymous.
  3. On Users tab: In User Authentication Methods, verify that Certificate is checked. If it is not, check it.
  4. If you have changed any settings in the steps above, then restart the server by closing the app, choosing to save the changes, and running it again.
  5. Copy the user certificate file in the DER format (in our example, the user_certificate.der file) to the certs subfolder of the server's user certificate store.

For troubleshooting, server logs can be found here: C:\Users\username\.prosysopc\prosys-opc-ua-simulation-server\log\simulationserver.log .

Certificate extensions issue

If everything is set up right, but you are getting BadIdentityTokenRejected errors reported by the client: From a discussion with Prosys developer, it appears that the server (we tested version 5.6.0-6) is incorrectly refusing user certificates that do not contain the key usage extensions that are actually required for application certificates only. We suppose that this will be fixed in later versions. To work around this issue, in server menu, select Options -> Preferences, and check Ignore Key Usage Certificate Checks (be aware that this also probably has effect on weakening the client instance certificate checks).

Alternatively, you can modify the statement for user certificate generation to include all extensions required by the server, as follows:

%openssl% req -x509 -new -nodes -key user_private_key.pem -days 365 ^
  -out user_certificate.pem ^
  -subj "/C=US/O=MyCompany/CN=John Doe" ^
  -addext "keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment" ^
  -addext "extendedKeyUsage = clientAuth" ^
  -addext "basicConstraints = critical, CA:FALSE"

(Credits: forum user 'Cwardltu')

Associated files

File:7408.zip