Erstellen von OPC UA Clients mit Sicherheitsunterstützung
Eines der Hauptmerkmale von OPC UA ist die Unterstützung von Sicherheit, was bedeutet, dass wir ein kryptografisch verschlüsseltes und signiertes Protokoll, Benutzerauthentifizierung und Autorisierungsunterstützung erhalten.
Damit dies funktioniert, muss jede Anwendungsinstanz (Installation eines Programms) ihre eigene Application Instance Certificate
und den entsprechenden privaten Schlüssel haben.
Die Anwendungen können entweder selbst signierte Zertifikate generieren, einige von einer Zertifizierungsstelle unter Verwendung von OPC UA GDS erhalten oder einfach mit Zertifikaten konfiguriert werden, die vom Benutzer manuell erstellt wurden.
Da Qt OPC UA zur Zeit weder Zertifikatsgenerierung noch GDS unterstützt, wird in diesem Tutorial beschrieben, wie man ein selbstsigniertes OPC UA Zertifikat auf der Kommandozeile mit OpenSSL generiert.
Erstellen Sie ein neues Anwendungszertifikat
Um ein korrektes x509v3 Zertifikat mit allen erforderlichen Erweiterungen für OPC UA erzeugen zu können, müssen wir zunächst eine Konfigurationsdatei mit allen notwendigen Informationen erstellen.
Denken Sie daran, subject
und subjectAltName
entsprechend Ihrem Fall zu ändern.
Es ist wichtig, dass Sie die ApplicationURI
der Anwendung in das URI
Feld von subjectAltName
einfügen, und dass der Hostname Ihres PCs oder Geräts in das DNS
Feld von subjectAltName
eingefügt wird. Alternativ können Sie das IP
Feld verwenden, wenn Ihr Gerät keine Hostnamen unterstützt und Sie mit statischen IPs arbeiten. Zukünftige Versionen von Qt OPC UA werden in der Lage sein, das Zertifikat mit den korrekten Informationen für Sie zu generieren. Im Moment können Sie es mit dem OpenSSL-Befehlszeilentool erstellen.
Beispiel: opcuaviewer.config
[ 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 = critical, CA:FALSE keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment extendedKeyUsage = clientAuth subjectAltName = URI:urn:foo.com:The%20Qt%20Company:QtOpcUaViewer,DNS:foo.com subjectKeyIdentifier = hash authorityKeyIdentifier=keyid:always,issuer:always [ subject ] countryName = DE stateOrProvinceName = Berlin localityName = Berlin organizationName = The Qt Company commonName = QtOpcUaViewer
Mit dieser Konfigurationsdatei ist OpenSSL in der Lage, ein passendes Zertifikat für die lokale Verwendung zu erstellen.
# create a self-signed certificate and private key openssl req -new -x509 -config opcuaviewer.config -newkey rsa:2048 -keyout opcuaviewer.key -nodes -outform der -out opcuaviewer.der # install the certificate and key into the application PKI directory mv opcuaviewer.der /path/to/application/pki/own/certs/opcuaviewer.der mv opcuaviewer.key /path/to/application/pki/own/private/opcuaviewer.pem # secure private key file permissions chmod 600 /path/to/application/pki/own/private/opcuaviewer.pem
Es ist wichtig, die Dateiberechtigung des privaten Schlüssels so zu sichern, dass nur die UA-Anwendung ihn lesen kann. Für Dienste (Daemons) empfiehlt es sich, dafür eigene unprivilegierte Benutzerkonten anzulegen und diesen Benutzer zum Eigentümer des Schlüssels zu machen. Bei interaktiven Anwendungen sollte dieser Schlüssel individuell für den Benutzer sein. Bei interaktiven Anwendungen ist es auch möglich, den Schlüssel mit einem Passwort zu schützen. In diesem Fall muss der Benutzer das Kennwort jedes Mal eingeben, wenn die Anwendung gestartet wird und der Schlüssel geladen wird. Aus diesem Grund sind passwortgeschützte Schlüssel keine gute Lösung für unbeaufsichtigte Anwendungen, da in diesem Fall das Passwort in einer Konfigurationsdatei gespeichert werden müsste.
Sie können die Zertifikatsdaten mit OpenSSL auslesen, um den Inhalt des Zertifikats zu untersuchen:
openssl x509 -in opcuaviewer.der -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: be:aa:41:79:8a:b0:4f:9a Signature Algorithm: sha512WithRSAEncryption Issuer: C = DE, ST = Berlin, L = Berlin, O = The Qt Company, CN = QtOpcUaViewer Validity Not Before: Nov 7 14:38:52 2018 GMT Not After : Dec 7 14:38:52 2018 GMT Subject: C = DE, ST = Berlin, L = Berlin, O = The Qt Company, CN = QtOpcUaViewer Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: [ skipped ] Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: critical Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Certificate Sign X509v3 Subject Alternative Name: URI:urn:foo.com:The%20Qt%20Company:QtOpcUaViewer, DNS:foo.com X509v3 Subject Key Identifier: B2:E8:5E:34:21:EA:67:CF:61:FC:14:94:18:C1:AD:13:89:83:CA:9B X509v3 Authority Key Identifier: keyid:B2:E8:5E:34:21:EA:67:CF:61:FC:14:94:18:C1:AD:13:89:83:CA:9B DirName:/C=DE/ST=Berlin/L=Berlin/O=The Qt Company/CN=QtOpcUaViewer serial:BE:AA:41:79:8A:B0:4F:9A Signature Algorithm: sha512WithRSAEncryption [ skipped ]
Konfigurieren der UA-Anwendung
Damit die Sicherheit mit dem im vorherigen Schritt erstellten Zertifikat funktioniert, ist es wichtig, dass
- Konfigurieren Sie die richtige Anwendungsidentität
m_identity = m_pkiConfig.applicationIdentity();
- Konfigurieren Sie die PKI-Speicherorte, damit das SDK das Zertifikat, den privaten Schlüssel, die Vertrauensliste usw. finden kann.
Siehe z. B. den Code aus dem Qt OPC UA Viewer-Beispiel:
void MainWindow::setupPkiConfiguration() { const QDir pkidir =QDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/pki"); if (!pkidir.exists() && !copyDirRecursively(":/pki", pkidir.path())) qFatal("Could not set up directory %s!", qUtf8Printable(pkidir.path())); m_pkiConfig.setClientCertificateFile(pkidir.absoluteFilePath("own/certs/opcuaviewer.der")); m_pkiConfig.setPrivateKeyFile(pkidir.absoluteFilePath("own/private/opcuaviewer.pem")); m_pkiConfig.setTrustListDirectory(pkidir.absoluteFilePath("trusted/certs")); m_pkiConfig.setRevocationListDirectory(pkidir.absoluteFilePath("trusted/crl")); m_pkiConfig.setIssuerListDirectory(pkidir.absoluteFilePath("issuers/certs")); m_pkiConfig.setIssuerRevocationListDirectory(pkidir.absoluteFilePath("issuers/crl")); const QStringList toCreate = { m_pkiConfig.issuerListDirectory(),m_pkiConfig.issuerRevocationListDirectory() }; for(const QString &dir: toCreate) { if (!QDir().mkpath(dir)) qFatal("Could not create directory %s!", qUtf8Printable(dir)); } }
Im Beispiel extrahieren wir vorkonfigurierte eigene und vertrauenswürdige Zertifikate aus dem Qt-Ressourcensystem an einen beschreibbaren Ort im Dateisystem. Die übrigen Verzeichnisse für Aussteller-(Sperr-)Listen werden manuell erstellt.
PKI-Ordner-Layout
Qt OPC UA verwendet das folgende Ordnerlayout:
Ordner | Beschreibung |
---|---|
eigene | Ort, an dem die eigenen Zertifikate der Anwendung gespeichert werden. |
vertrauenswürdig | Eine Liste von vertrauenswürdigen Anwendungszertifikaten oder vertrauenswürdigen CA-Zertifikaten. |
aussteller | Eine Liste von Zertifikaten für CAs, die nicht vertrauenswürdig sind, aber zur Überprüfung von Signaturen auf Zertifikaten benötigt werden. |
abgelehnt | Hier speichert die Anwendung abgelehnte Zertifikate, so dass sie später von einem Administrator als vertrauenswürdig eingestuft werden können. Es ist wichtig, dass hier eine maximale Anzahl von Dateien konfiguriert ist. Wenn diese erreicht ist, sollte die älteste Datei zuerst gelöscht werden. Ohne ein Limit könnte ein Angreifer die Festplatte des Rechners mit ungültigen Verbindungsversuchen füllen. |
Jeder der Ordner own
, trusted
und issuers
enthält die in der folgenden Tabelle definierte Unterverzeichnisstruktur.
Unterverzeichnis | Beschreibung |
---|---|
certs | Enthält die DER-kodierten X.509 v3-Zertifikate. Die Dateien müssen eine .der-Dateierweiterung haben. |
privat | Enthält die privaten Schlüssel. Das Format der Datei kann backendspezifisch sein. PEM-kodierte Dateien sollten eine .pem-Erweiterung haben. PKCS#12-kodierte Dateien sollten die Endung .pfx haben. Der Name der Stammdatei muss mit dem Namen der entsprechenden öffentlichen Schlüsseldatei im certs-Verzeichnis übereinstimmen. Dieser Ordner existiert nur innerhalb des Ordners own . |
crl | Enthält die DER-kodierte CRL für alle CA-Zertifikate, die sich in den certs-Verzeichnissen befinden. Die Dateien müssen eine .crl-Dateierweiterung haben. |
Erste Verbindung
Bei der ersten Verbindung muss der Client dem Serverzertifikat vertrauen.
Der Client sollte eine Zertifikatswarnung (mit Zertifikatsdetails) anzeigen und die Möglichkeit bieten, das Zertifikat in seiner Vertrauensliste zu speichern. Ein Beispiel finden Sie unter Qt OPC UA Viewer Example.
Wenn der Client das Serverzertifikat akzeptiert hat, können Sie erneut versuchen, eine Verbindung herzustellen. Nun kann es sein, dass der Server das Zertifikat des Clients ablehnt. Dies wird durch den generischen Fehlercode BadSecurityChecksFailed
angezeigt. Server speichern abgelehnte Zertifikate normalerweise in einem speziellen Ordner rejected
. Der Administrator kann diese in die Vertrauensliste verschieben, um den Clients zu vertrauen. Dies erspart das manuelle Kopieren des Client-Zertifikats auf den Server.
Sobald der Server dem Client vertraut hat, sollten Sie eine sichere Verbindung herstellen können.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.