There are many tools available to generate self-signed certificates.

OpenSSL

Here is an example of how to use OpenSSL to generate self-signed x509 v3 certificates. This example works on Linux. Anyway, OpenSSL is available on Windows platform as well.

Install OpenSSL if it is not installed yet:

sudo apt update
sudo apt install openssl

Create cert.cnf with the following content:

[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no

[req_distinguished_name]
O = MyCompany
OU = MyDivision
CN = MyDevice

[v3_req]
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = deviceName
IP.1 = 192.168.0.1

Fill [req_distinguished_name] and [alt_names] sections appropriately. As a recomendation, CN should refer to target device. Take into account, DNS and IP are validated by client when esteblishing a connection to OPCUA server.

Generate private key:

openssl genrsa -out my.key 2048

Now, generate self-signed certificate.

openssl req -key my.key -new -x509 -days 365 -config cert.cnf -out my.cert

As a result, two files are created. my.key is a private key file which should be kept in secret and my.cert is a certificate file. Both are in PEM format.

Use the following command to display certificate content:

openssl x509 -in my.cert -text -noout

PowerShell

Here is an example of how to use PowerShell scripts to generate self-signed x509 v3 certificates. Take into account, proposed example works with PowerShell 7.1 and higher.

Define certificate subject, DNS name and certificate location:

$certSubject = "O=MyCompany,OU=MyDivision,CN=MyDevice";
$certDns = "deviceName";
$certLocation = "Cert:\CurrentUser\My";

Generate self-signed certificate:

$cert = New-SelfSignedCertificate -Subject $certSubject -DnsName $certDns -Type Custom -KeyAlgorithm RSA -KeyLength 2048 -KeyExportPolicy Exportable -KeyUsage DigitalSignature,DataEncipherment,KeyEncipherment -CertStoreLocation $certLocation;

Export certificate to PEM format:

$certOut = [System.Security.Cryptography.PemEncoding]::Write("CERTIFICATE", $cert.RawData);
[IO.File]::WriteAllBytes("my.cert", $certOut);

Export private key:

$keyOut = [System.Security.Cryptography.PemEncoding]::Write("PRIVATE KEY", $cert.PrivateKey.ExportPkcs8PrivateKey());
[IO.File]::WriteAllBytes("my.key", $keyOut);

As a result, two files are created. my.key is a private key file which should be kept in secret and my.cert is a certificate file. Both are in PEM format.

Use the following OpenSSL command to display certificate content:

openssl x509 -in my.cert -text -noout