2017-07-14 3 views
2

Ich bin neu zu Opc ua und kein Profi in Java. Beim Einrichten eines Clients in Java habe ich Probleme mit dem Zertifikats-Dealing. Ich möchte eine Verbindung zum Server über Basic 256, SignAndEncrypt herstellen. Soweit ich weiß, wird in dieser Sicherheitsstufe ein vom Client erstelltes oder geladenes Zertifikat an den Server gesendet, wo es akzeptiert werden muss. Der Server sendet dann ein Zertifikat zurück an den Client, der dann vom Client akzeptiert werden muss. Bitte korrigiere mich wenn ich falsch liege.Wie akzeptiere ich das Zertifikat von einem Server?

Erstellen/ein Zertifikat auf der Clientseite wird geladen und es an den Server gesendet hat bereits gut funktionieren (siehe Code unten) und dann kann ich es auf der Seite Server akzeptieren manuell. Aber danach stecke ich fest: Wie kann ich diese Zertifikatsüberprüfung in meinem Code sehen und wie kann ich das Serverzertifikat finden, geschweige denn akzeptieren? Ich habe den SampleConsoleClient von opc ua für einige Orientierung während der Implementierung verwendet. Aber im Gegensatz dazu verwende ich keine Benutzereingaben.

Hier einige bisher von meinem Code.

Initialisierung:

try { 
     client = new UaClient(serverUri); 
    } catch (final URISyntaxException e) { 
     throw new InitializationException("The server uri has an invalid syntax.", e); 
    } 
    try { 
     client.setApplicationIdentity(createApplicationIdentity()); 
    } catch (final SecureIdentityException e) { 
     throw new InitializationException(
       "Application Identity could not be created due to a Security Identity Exception.", e); 
    } catch (final IOException e) { 
     throw new InitializationException("Application Identity could not be created due to an IO Exception.", 
       e); 
    } 

createApplicationIdentity():

final ApplicationDescription appDescription = new ApplicationDescription(); 
    appDescription.setApplicationName(new LocalizedText(APPLICATION_NAME, Locale.ENGLISH)); 
    appDescription.setApplicationUri(APPLICATION_URI); 
    appDescription.setProductUri(PRODUCT_URI); 
    appDescription.setApplicationType(ApplicationType.Client); 

    // Setting security features 
    client.setSecurityMode(SecurityMode.BASIC256_SIGN_ENCRYPT); 
    client.setCertificateValidator(validator); 
    validator.setValidationListener(myValidationListener); //myValidationListener is similar to most lines in MyCertificateValidationListener in the opc ua samples 
    final File privatePath = new File(validator.getBaseDir(), "private"); 
    final KeyPair issuerCertificate = null; 
    final int[] keySizes = null; 
    final ApplicationIdentity identity = ApplicationIdentity.loadOrCreateCertificate(appDescription, 
      "Sample Organisation", "opcua", privatePath, issuerCertificate, keySizes, true); 
    identity.setApplicationDescription(appDescription); 
    return identity; 

Nach der Initialisierung, ich versuche, so zu verbinden (mit Anmerkung, wie ich die Verbindung vorstellen, richtig funktionieren könnte):

012.351:

und der Fehler wird, dass geworfen

WARN (?:?): /<IPofServer> Error org.opcfoundation.ua.common.ServiceResultException: Bad_SecurityChecksFailed 
(0x80130000) "An error occurred verifying security." at 
org.opcfoundation.ua.transport.tcp.io.TcpConnection$ReadThread.run(Unknown Source) 
com.prosysopc.ua.client.ConnectException: Failed to create secure channel to server: : opc.tcp://<IPofServer> 
[http://opcfoundation.org/UA/SecurityPolicy#Basic256,SignAndEncrypt] 
ServiceResult=Bad_SecurityChecksFailed (0x80130000) "An error occurred verifying security." 
at com.prosysopc.ua.client.UaClient.n(Unknown Source) 
at com.prosysopc.ua.client.UaClient.connect(Unknown Source) 
at *lineOfCode* 
Caused by: org.opcfoundation.ua.common.ServiceResultException: 
Bad_SecurityChecksFailed (0x80130000) "An error occurred verifying security." 
at org.opcfoundation.ua.transport.tcp.io.TcpConnection$ReadThread.run(Unknown Source) 

Mit dem lineOfCodeclient.connect() zu sein.

Vielen Dank im Voraus für die Hilfe !!

Antwort

1

Der Server sendet das Zertifikat an den Client. Der Kunde hat dann

  1. die Gültigkeit des Zertifikats überprüfen. Dies bedeutet, dass die Signatur des Zertifikats überprüft wird, die Gültigkeit überprüft wird, ob der Hostname im Zertifikat mit dem Hostnamen im Endpunkt übereinstimmt, CRLs usw. überprüft werden. Normalerweise sollte das SDK (der Validator) dies für Sie tun, aber Sie müssen möglicherweise einige Parameter in den Validator einspeisen, welche Prüfungen tatsächlich durchgeführt werden sollten. Die Sicherheitsrichtlinie Basic256 stellt einige minimale Anforderungen an das Zertifikat, das das Zertifikat natürlich erfüllen sollte. Sie können die Anforderungen hier überprüfen: http://opcfoundation-onlineapplications.org/profilereporting/ - gehen Sie zu Sicherheitskategorie -> Facetten -> Sicherheitsrichtlinie.
  2. prüft, ob das Server-Zertifikat ist vertraut. Dies läuft normalerweise darauf hinaus, zu überprüfen, ob eine Kopie des Zertifikats (puclic key) in einen Zertifikatsspeicher gelegt wurde, der als Truststore ausgewählt wurde. Wenn Sie den Client schreiben, liegt es an Ihnen zu sagen, welcher Speicher zu wählen ist, aber Sie müssen dem Validator mitteilen, wo er suchen soll. Ich weiß nicht viel über OPc UA Entwicklung in Java, aber Sie sollten überprüfen, welches Zertifikat speichert der Validator erwartet. Vielleicht gibt es eine Standard-Schlüsseldatei.

(Auf der Serverseite passiert das gleiche mit dem Client-Zertifikat). Diese

asssumes Sie beginnen mit selbst signierten Zertifikaten.Wenn Sie von einer Zertifizierungsstelle signierte Zertifikate verwenden, müssen beide Anwendungen (Server und Client) in der Lage sein, die gesamte Kette der anderen Partei zu überprüfen. Es kann lokal in einem Geschäft gespeichert werden oder kann von der anderen Partei gesendet werden. Mindestens ein Zertifikat in der Kette muss am strengsten sein (muss in den Trust Store gelegt werden).

Für eine allgemeine Beschreibung, wie UA Sicherheits Werke haben einen Blick auf diesen Link: https://opcfoundation.org/wp-content/uploads/2014/08/11_OPC_UA_Security_How_It_Works.pdf

Für eine detaillierte Darstellung Sie die Spezifikation konsultieren sollte, bei GitHub verfügbar.

Edit: eine zusätzliche Bemerkung, die hier helfen kann: Sie scheinen ein SDK für den fraglichen Zweck zu verwenden. Während die Validierung von Zertifikaten, d. H. Die Durchführung von Signaturprüfungen usw., normalerweise von einem solchen SDK abgedeckt wird, ist die Konfiguration der Anwendung die Aufgabe der Anwendung (Programmierer). Dies umfasst den Speicherort, an dem Sie vertrauenswürdige Zertifikate speichern und wo und wie Sie fehlende Teile von Zertifikatsketten sammeln. Sie sollten zunächst versuchen zu überprüfen, wie Demo-Clients und Server mit dieser Aufgabe umgehen, also die Konfigurationsaufgaben für solche Anwendungen überprüfen, indem Sie versuchen, eine sichere Verbindung von UA ​​Expert zu den Beispielservern von der OPC-Foundation herzustellen. Im .Net-SDK der OPC-Foundation ist der Speicherort für den Truststore standardmäßig ein bestimmtes Verzeichnis im Dateisystem (ein Unterordner von C:\ProgramData\OpcFoundation, es ist nur Windows). Sie können dies jedoch überschreiben, wenn Sie den Validator initialisieren. Andere Clients verwenden ihre eigene Verzeichnisstruktur für die Speicherung vertrauenswürdiger Zertifikate

+0

Vielen Dank für Ihre Antwort! Ich verstehe, dass ich mit dem Zertifikat umgehen muss, das vom Server gesendet wird. Meine Frage war mehr _programmatisch_, da ich hier wirklich leer bin: Ich habe einen Validator gesetzt (siehe Code oben) und wenn ich die Zertifikate vor und nach 'client.connect()' über 'validator.getRejected/Reloved/TrustedCertificates überprüfe. length() 'Ich bekomme '0' als Antwort für alle drei Arten von Zertifikaten vor und nach der Verbindung. Sollte nicht mindestens eins im abgelehnten Verzeichnis sein? – Nanda

+0

@Nanda Ich habe mehr Erfahrung mit dem .Net Base Case, aber ich würde einen ähnlichen Ansatz in Java erwarten. In Opc UA muss der Client dem Server vertrauen (Schritt 2 in meiner Antwort). Dies wird normalerweise dadurch erreicht, dass das Serverzertifikat an einem bestimmten Ort abgelegt wird. Dieser Ort muss Ihrer Anwendung bekannt gegeben werden, und hier müssen Sie (programmatisch) etwas unternehmen. Sie müssen herausfinden, wie Sie dem Validator mitteilen können, wo nach den (vertrauenswürdigen) Zertifikaten gesucht werden soll. Wenn der Validator diese Art von Eigenschaften nicht zur Verfügung stellt, müssen Sie das Vertrauen selbst irgendwie überprüfen, aber ich glaube das nicht. Ein – Thomas

+0

Grund für mich zu glauben, dass der Validator ein TrustedCertifcates Attribut hat. Ich würde erwarten, dass die Anwendung den Inhalt eines Speichers in diese Variable zu einem bestimmten Zeitpunkt laden würde. Wenn Sie debuggen, wie diese "TrustedCertificates" -Variable initialisiert wird, sollten Sie einen Hinweis erhalten, wie dies zu tun ist. – Thomas

0

Sie beziehen sich offensichtlich auf die Prosys OPC UA Java SDK.

Was immer zuerst passiert, wenn Sie zum ersten Mal versuchen, eine sichere Verbindung herzustellen, ist, dass der Server den Zugriff auf Ihre Clientanwendung verweigert - und Bad_SecurityChecksFailed zurückgibt.

Nur nachdem Sie dem Server gesagt haben, dass er (das Zertifikat) Ihrer Client-Anwendung vertrauen soll, gelangen Sie in die Phase, in der die Client-Anwendung versuchen wird, das Zertifikat des Servers zu überprüfen - und Ihr 'validationListener' wird ausgelöst.

0

Vielen Dank für Ihre Antworten. In der Zwischenzeit habe ich versucht, die Methoden connect() und initalize() aus SampleConsoleClient in den Prosys SDK-Beispielen zu kopieren/einfügen und zu modifizieren. Und das hat funktioniert. Ich vermute, es hatte etwas damit zu tun, einige Informationen zu erneuern, aber ich bin mir nicht ganz sicher ... Fakt ist, meine Bewerbung funktioniert jetzt, aber danke für Ihre Bemühungen!

Verwandte Themen