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
SHA1fingerprint 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
where#! /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.dercert.confcontains[ 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 = PythonOpcUaServerHint
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")
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:
-
What do the commands
openssl genrsa -out server_private.pem 2048andopenssl req -x509 -days 365 -new -out certificate.pem -key server_private.pem -config cert.confexactly? -
How would you install the root certificate under a)
Windows 11, b)MacOS, c)Linux, d)Androidand e)iOS? -
What would you need to pay especially attention to in case you were to run your own
PKI?