Skip to content

PKI (Public Key Infrastructure) in OT

Exercice 1 : Checking a 1st certificate

Take a known site and check its validity. For instance, go to https://www.deepl.com/ and check out:

  • Certificate validity
  • Extended Key Usage
  • Number of binary forms a certificate can be retrieved and analyzed
  • Find the SHA1 fingerprint in the exported certificate

Is this according to your expectations as far as a commercial company is concerned?

Exercice 2 : Quantum-safe cryptography

In Quantum-safe cryptography – fundamentals, current developments and recommendations, the BSI (German Federal Office for Information Security) gives recommandations about the posture to adopt. Can you :

  • name the recommandations
  • state whether it is more important to adopt Quantum Key Distribution or Post Quantum Algorithms? Why?
  • explain whether the present PKI architecture (X.509, hierarchical structure, …) is ready for post-quantum cryptography

Exercice 3 : Implement a securely communicating OPC UA Server

In a previous exercice, you have secured the communication to your OPC UA server. Should you have not, below you will find code snippets that will help you to do so.

Your task: based on the following scripts for generating the required certificates, modify them so that the certificates are signed by an intermediary CA and not a self-signed one (pretending to be root CA).

Certificate generation

  • generating the key for the OPC UA server

    #! /bin/bash
    
    openssl genrsa -out server_private.pem 2048
    
    openssl req -x509 -days 365 -new -out certificate.pem -key server_private.pem -config cert.conf
    openssl x509 -outform der -in certificate.pem -out certificate.der
    
    where cert.conf contains
    [ req ]
    default_bits = 2048
    default_md = sha256
    distinguished_name = subject
    req_extensions = req_ext
    x509_extensions = req_ext
    string_mask = utf8only
    prompt = no
    
    [ req_ext ]
    basicConstraints = CA:FALSE
    nsCertType = client, server
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyCertSign
    extendedKeyUsage= serverAuth, clientAuth
    nsComment = "OpenSSL Generated Certificate"
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid,issuer
    subjectAltName = URI:urn:opcua:python:server,IP: 127.0.0.1
    
    
    [ subject ]
    countryName = CH
    stateOrProvinceName = ZH
    localityName = Zurich
    organizationName = Test
    commonName = PythonOpcUaServer
    

    Hint

    Adapt the information to make it yours 😉

  • generating the key for a client

    #! /bin/bash
    
    # Check if a name parameter is provided
    if [ -z "$1" ]; then
    echo "Usage: $0 <name>"
    exit 1
    fi
    
    # Use the provided name for the certificate and private key
    NAME=$1
    
    # Generate the private key
    openssl genrsa -out "${NAME}_private.pem" 2048
    openssl rsa -in "${NAME}_private.pem" -outform DER -out "${NAME}_private.der"
    
    # Generate the certificate
    openssl req -new -x509 -key "${NAME}_private.pem" -out "${NAME}_cert.pem" -days 365
    openssl x509 -outform der -in "${NAME}_cert.pem" -out "${NAME}_cert.der"
    
    echo "Certificate and private key generated:"
    echo "  Private Key: ${NAME}_private.key"
    echo "  Certificate: ${NAME}_cert.pem"
    

Server code

After namespace = server.register_namespace(Settings.service_name), add the following lines :

server.load_certificate("certificates/certificate.der")
server.load_private_key("certificates/server_private.pem")
server.set_security_policy([
                                #ua.SecurityPolicyType.NoSecurity,
                                #ua.SecurityPolicyType.Basic128Rsa15_Sign,
                                #ua.SecurityPolicyType.Basic128Rsa15_SignAndEncrypt,
                                #ua.SecurityPolicyType.Basic256Sha256_Sign,
                                ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt
                            ])

Warning

Depending what modes are activated, you will need to modify certificates and client code accordingly.

Bug

The GUI client (opcua-client) is currently not capable of connecting to the server and throws an error. Just use the command line alternative as the exercice is to have a secured channel established and, especially, have a PKI in place for handling the certificates.

Client code

from opcua import Client
import logging
from enviro import Settings

# Create a dedicated logger
logger = logging.getLogger('opcua_cont_client')
logger.setLevel(logging.INFO)

# Create console handler and set level to info
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)

# Create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# Add formatter to ch
ch.setFormatter(formatter)

# Add ch to logger
logger.addHandler(ch)

# OPC UA Server Python
url = Settings.server_url 
client = Client(url)

if Settings.secure_communication:
    #client.set_user("user1")
    #client.set_password("pw1")
    client.set_security_string("Basic256Sha256,SignAndEncrypt,certificates/trusted_clients/client3_cert.der,certificates/trusted_clients/client3_private.pem")
    client.secure_channel_timeout = 100000
    client.session_timeout = 100000

try:
    client.connect()
    root = client.get_root_node()
    nodeId = root.get_child(["0:Objects", "2:Sensors", "2:Temperature"])
    logger.info("OPC UA Client Connected")
    logger.info(f"NodeId: {nodeId}")
    node = client.get_node(nodeId)
    value = node.get_value()
    logger.info(f"Value[°C]: {value}")

except Exception as e:
    logger.error(f"Connection failed: {e}")

finally:
    client.disconnect()

Warning

You will need to add secure_communication = True to Settings class (enviro.py).

Note

As you can see, the code contains

#client.set_user("user1")
#client.set_password("pw1")
In fact, the code would support user/password login - even though it is not recommended.

Exercice 4 : Run Your Own PKI

Aim

In fact, in the previous exercice you embarked in an exciting adventure: you will become a Certificate Authority!!! Congratulations!!! 😎

After following the indications given in the previous exercice, where you a) created the CA private key and b) generated the root certificate, go about answering the following:

  1. What do the commands openssl genrsa -out server_private.pem 2048 and openssl req -x509 -days 365 -new -out certificate.pem -key server_private.pem -config cert.conf exactly?

  2. How would you install the root certificate under a) Windows 11, b) MacOS, c) Linux, d) Android and e) iOS?

  3. What would you need to pay especially attention to in case you were to run your own PKI?