Autor Thema: Roter Java-Fehler  (Gelesen 2824 mal)

saschko

  • Newbie
  • *
  • Beiträge: 3
  • Gerät: Sony z3 compact
  • Version: 4.4.4
Roter Java-Fehler
« am: 13.11.2014, 17:04:10 »
Hallo (und vielen Dank für die tolle App),

ich versuche gerade, die Verbindung zu meinem FHEM-Homeserver hinzubekommen. Ich habe zunächst testweise das ganze ohne Absicherung laufen lassen (also http, keine Zertifikate, keine Passwörter etc.). Funktioniert. Und funktioniert auch von außerhalb über dyndns der Fritz-Box (*.myfritz.net:8088 leitet weiter auf meinen FHEM-Server, der auf einer Synology-Diskstation läuft). Aber ich will das Tor natürlich nicht dauerhaft offen lassen. Deswegen habe ich in FHEM nun alles umgestellt:

- HTTPS aktiviert
- Benutzername und Passwort vergeben
- Server und Client-Zertifikat erstellt
- Client-Zertifikat auf das Handy kopiert (in den egigeozone-Ordner)

Leider funktioniert das aber so nicht, ich bekomme die folgenden Fehlermeldungen im EgiGeoZone-Log (auch in Rot als Handy-Benachrichtigung):

Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:113)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory.engineGenerateCertificate(OpenSSLX509CertificateFactory.java:270)
   ... 19 more
Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
   at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:71)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:224)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:214)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:104)
   ... 20 more
Caused by: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
   at com.android.org.conscrypt.NativeCrypto.d2i_X509_bio(Native Method)
   at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:65)
   ... 23 more


Mit identischen Einstellungen inkl. identischem Client-Zertifikat in der AndFHEM-App funktioniert der Kontakt zum Server aber. Woran kann es liegen?

Hier noch mal meine Einstellungen (die genau so auch in ANdFHEM erfolgreich hinterlegt sind):
Zone: home
URL: https://<IP>:8083/fhem/geo
keine Zone verlassen/betreten (weil allgemeine URL)
Benutzer: benutzername
Passwort: passwort
kein PKCS12-Zertifikat & kein zugehöriges Passwort
Ausstellerzertifikat fhem.pem (die Datei liegt auch in "../egigeozone"
Timeout: 30

Viele Grüße
saschko

Admin

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 769
    • EgiGeoZone
  • Gerät: Xiaomi Redmi Note 5, Samsung Galaxy Note 2, S4, S5, S2, S7
  • Version: MIUI 10.0 Global, Android 4.4, 5, 6, 7, 8, 8.1, 12, 13
Re: Roter Java-Fehler
« Antwort #1 am: 13.11.2014, 20:10:05 »
Willkommen im Forum!

Leider funktioniert das aber so nicht, ich bekomme die folgenden Fehlermeldungen im EgiGeoZone-Log (auch in Rot als Handy-Benachrichtigung):

Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:113)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory.engineGenerateCertificate(OpenSSLX509CertificateFactory.java:270)
   ... 19 more
Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
   at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:71)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:224)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:214)
   at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:104)
   ... 20 more
Caused by: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
   at com.android.org.conscrypt.NativeCrypto.d2i_X509_bio(Native Method)
   at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:65)
   ... 23 more

Ich vermute mal, dass Du für diese Applikation einen Apache-Server im Einsatz hast. Wenn nicht, dann ist das Fehlerbild trotzdem so, wie wenn es ein Apache wäre.
Also ich vermute mal, dass du die Zertifikate bei der Konfiguration vom Server vertauscht hast oder gar falsche hinterlegt hast.
Mit folgenden Befehl kannst du mal sehen, was in denn hinterlegten Zertifikaten enthalten ist. Hier mal ein Beispiel. Du solltest dabei deine Zertifikate mit dem richtigen Pfad angeben:
openssl x509 -text -noout -in /usr/local/etc/apache22/certs/server.pem

Mit identischen Einstellungen inkl. identischem Client-Zertifikat in der AndFHEM-App funktioniert der Kontakt zum Server aber. Woran kann es liegen?

Coole Sache! Ich habe nämlich für Matthias von andFhem bei der Einbindung der Zertifikatsgeschichte mitprogrammiert und es ist teilweise der gleiche Code an der Stelle implementiert.

Da muss sich eine der Apps anders verhalten, keine Ahnung aber, was der Unterschied ist.

Mir ist noch aufgefallen, dass du schreibst "kein PKCS12-Zertifikat & kein zugehöriges Passwort". Also kein privates Zertifikat verwendet?

Melde dich wieder, sobald sich was Neues ergibt.
Schöne Grüße
Egmont

saschko

  • Newbie
  • *
  • Beiträge: 3
  • Gerät: Sony z3 compact
  • Version: 4.4.4
Re: Roter Java-Fehler
« Antwort #2 am: 13.11.2014, 23:32:47 »
Lieber Emont,

erstmal vielen Dank für deine schnelle Antwort. Ich habe heute vieles weiter probiert, kann das Problem aber noch nicht lösen.

Ich muss zugeben, dass mit den Zertifikaten habe ich noch nicht richtig verstanden. Ich habe wie hier beschrieben (http://www.fhemwiki.de/wiki/FritzBox_Webzugriff_absichern) eine server-cert.pem und eine server-key.pem erstellt. Auf meiner Synology Diskstation, auf der der FHEM läuft. Im Ordner /usr/local/FHEM/share/fhem/certs. Danach habe ich vermutlich wirklich beide Dateien vertauscht. Mittlerweile habe ich einen kleinen Fortschritt erreicht, aber es funktioniert irgendwie immer noch nicht. Und wie ich an ein privates PKCS12 komme ist mir auch unklar.

Kurz mal mein (vermutlich falsches, bisheriges) Verständnis der beiden Dateien: der server-cert.pem ist das Zertifikat des Servers. Dieses Zertifikat (bzw. einen Teil davon) sendet der Server aus, wenn jemand versucht, den Server zu erreichen. Deswegen muss dieses Server-Zertifikat auf dem Server liegen und liegen bleiben. Im dem Zertifikat steht unter anderem auch ein öffentlicher key (im Prinzip der gesamte Inhalt des server-key.pem). Mein Verständnis war: diesen öffentliche Schlüssel, also nur die Datei server-key.pem - muss an die clients verteilt werden. Und die Clients können mit diesem Schlüssel das, was der Server aussendet, verififzieren. Und wissen dann: das ist genau der Server, den ich erreichen wollte. Ich habe also nicht nur eine per SSL verschlüsselte Verbindung, sondern auch noch sichergestellt, mit wem (nämlich mit dem tatsächlichen Aussteller des Schlüssels).
Ich dachte außerdem, dass man sich dann noch zusätzlich (optional) auch als client gegenüber dem Server mit einem persönlichen Zertifikat verifizieren kann. Darum wollte ich mich dann aber später kümmern. Eine BasicAuth gibt es ja bereist. Und die Kommunikation sollte durch die ersten beiden Dateien bereits abgesichert sein.

Davon abweichend habe ich jetzt aber einfach mal trotzdem beide Dateien (die server-cert.pem und die server-key.pem) auf das smartphone geladen und damit getestet.

Wenn ich die lokale IP für den FHEM-Server in der app eingegebe, funktioniert die Kommunikation mit dem Server:
URL https://192.168.5.100:8083/fhem/geo
nach wie vor kein PKCS12 (so eines habe ich ja gar nicht)
Aussteller-Zertifikat: server-cert.pem

Es funktioniert mit gleichen Einstellungen auch komplett OHNE Aussteller-Zertifikat. Aber NICHT mit einem falschen (z.b. dem server-key.pem, den ich gestern verwendet habe).

Wenn ich nun nichts ändere außer die URL und statt der IP-Adresse mein *.myfritz.net-DNS verwende, funktioniert die Kommunikation mit dem Server nicht. Und zwar weder mit dem server-cert.pem noch mit dem server-key.pem. Am dyndns liegt es aber nicht: ohne SSL/HTTPS funktioniert ein parallel auf einem anderen Port eingerichteter Server problemlos.

Eventuell liegt es tatsächlich daran, dass die Synology Diskstation so etwas wie einen Apache-Proxy automatisch verwendet. Und zwar nur, wenn von außen drauf zugegriffen wird und nicht bei direktem Aufrug per IP-Adresse. Ich habe da aber nichts selbst eingerichtet. Kann nur nicht ausschließen, dass die diskstation so was macht. Es gibt jedenfalls auch von Haus aus verschiedene Webserver, die auf anderen Ports der Diskstation laufen. Hast du eine Idee, wie ich das herausfinden oder beeinflussen kann?

Ich fürchte, dass es also insgesamt eher an meiner Konstellation hier liegt und verstehe auch, dass du dieses Problem dann nicht lösen kannst. Werde mir ohnehin auch aus anderen Gründen eventuell bald eine RPI zulegen und hoffe, dass das Einrichten dann problemloser funktioniert (falls es nicht doch noch eine schnelle Lösung gibt).

Kannst du mir denn erklären, wie ich aus den bisher vorhandenen 2 pem-Dateien (oder einfach zusätzlich) die benötigen PKCS12-Datei mit Passwort erstelle? Bzw. wo ich eine gute Anleitung dazu finde?

Viele Grüße
Sascha


Admin

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 769
    • EgiGeoZone
  • Gerät: Xiaomi Redmi Note 5, Samsung Galaxy Note 2, S4, S5, S2, S7
  • Version: MIUI 10.0 Global, Android 4.4, 5, 6, 7, 8, 8.1, 12, 13
Re: Roter Java-Fehler
« Antwort #3 am: 14.11.2014, 08:12:46 »
Guten Morgen Sascha,

die Sache mit den Zertifikaten ist echt nicht einfach  :)

Kurz mal mein (vermutlich falsches, bisheriges) Verständnis der beiden Dateien: der server-cert.pem ist das Zertifikat des Servers. Dieses Zertifikat (bzw. einen Teil davon) sendet der Server aus, wenn jemand versucht, den Server zu erreichen. Deswegen muss dieses Server-Zertifikat auf dem Server liegen und liegen bleiben. Im dem Zertifikat steht unter anderem auch ein öffentlicher key (im Prinzip der gesamte Inhalt des server-key.pem). Mein Verständnis war: diesen öffentliche Schlüssel, also nur die Datei server-key.pem - muss an die clients verteilt werden. Und die Clients können mit diesem Schlüssel das, was der Server aussendet, verififzieren. Und wissen dann: das ist genau der Server, den ich erreichen wollte. Ich habe also nicht nur eine per SSL verschlüsselte Verbindung, sondern auch noch sichergestellt, mit wem (nämlich mit dem tatsächlichen Aussteller des Schlüssels).
Ich dachte außerdem, dass man sich dann noch zusätzlich (optional) auch als client gegenüber dem Server mit einem persönlichen Zertifikat verifizieren kann. Darum wollte ich mich dann aber später kümmern. Eine BasicAuth gibt es ja bereist. Und die Kommunikation sollte durch die ersten beiden Dateien bereits abgesichert sein.

Was du da beschrieben hast, ist bis auf ein paar Begrifflichkeiten ganz in Ordnung.
Es ist so, dass nur der öffentliche Teil des Zertifikats auf die Clients verteilt werden sollte. Der Key bleibt immer auf dem Server und sollte geschützt werden!

Normalerweise erstellt man eine eigene CA (Austeller) auf seinem Server und erstellt, dann mit Hilfe dieser die Server- und Clientzertifikate. Dazu muss man im ersten Schritt Aussteller-Zertifikate (Rootzertifikate) erstellen, mit welchen man dann beim Erstellen der neuen Server- oder/und Clientzertifkate diese signiert. In so einem Fall, kann man den öffentlichen Teil des Ausstellerzerts. (oder eventuell die Kette) auf die Clients verteilen.
In deinem Falle ist das Serverzertifikat wahrscheinlich "selbstsigniert", also ohne einem einem Aussteller (CA) erstellt worden.

Am Besten du erstellst dir eine CA und erstellst damit ein neues Serverzert. und auch gleich ein Clientzert. in Form einer PKCS12-Datei.
Anbei eine gute Anleitung: https://gist.github.com/gbirke/8608543


Wenn ich die lokale IP für den FHEM-Server in der app eingegebe, funktioniert die Kommunikation mit dem Server:
URL https://192.168.5.100:8083/fhem/geo
nach wie vor kein PKCS12 (so eines habe ich ja gar nicht)
Aussteller-Zertifikat: server-cert.pem

Dass es nicht mit der externen Adresse funktioniert, liegt wahrscheinlich an deinen Weiterleitungen und den Webservern dazwischen.

Es funktioniert mit gleichen Einstellungen auch komplett OHNE Aussteller-Zertifikat. Aber NICHT mit einem falschen (z.b. dem server-key.pem, den ich gestern verwendet habe).

Die Ursache, warum es auch OHNE Aussteller-Zertifikat funktioniert ist einfach die, dass ich SSL auch ohne Aussteller-Zert. akzeptiere. Wer keines angibt, kann trotzdem per SSL arbeiten. Ist sich aber nicht sicher, mit welchem Server er spricht!
Diese Art von SSL-Behandlung ist Android-spezifisch. Android lässt nicht zu, eigene Aussteller-Zertifikate (Server-Zertifikate) in seinem Android-Zertifikate-Store hinzuzufügen. Damit der Normalanwender sich nicht mit der Zertifikatsthematik auch noch befassen muss, akzeptieren die meisten Apps eine SSL-Verbindung zu einem Server auch ohne Aussteller-Zertifikate. Dies gilt nur für selbserstellte Zertifikaten.

Wenn ich nun nichts ändere außer die URL und statt der IP-Adresse mein *.myfritz.net-DNS verwende, funktioniert die Kommunikation mit dem Server nicht. Und zwar weder mit dem server-cert.pem noch mit dem server-key.pem. Am dyndns liegt es aber nicht: ohne SSL/HTTPS funktioniert ein parallel auf einem anderen Port eingerichteter Server problemlos.

Eventuell liegt es tatsächlich daran, dass die Synology Diskstation so etwas wie einen Apache-Proxy automatisch verwendet. Und zwar nur, wenn von außen drauf zugegriffen wird und nicht bei direktem Aufrug per IP-Adresse. Ich habe da aber nichts selbst eingerichtet. Kann nur nicht ausschließen, dass die diskstation so was macht. Es gibt jedenfalls auch von Haus aus verschiedene Webserver, die auf anderen Ports der Diskstation laufen. Hast du eine Idee, wie ich das herausfinden oder beeinflussen kann?

Ich fürchte, dass es also insgesamt eher an meiner Konstellation hier liegt und verstehe auch, dass du dieses Problem dann nicht lösen kannst. Werde mir ohnehin auch aus anderen Gründen eventuell bald eine RPI zulegen und hoffe, dass das Einrichten dann problemloser funktioniert (falls es nicht doch noch eine schnelle Lösung gibt).
Kann dir leider da nicht helfen, da deine Infrastruktur und auch Synology nicht kenne.

Kannst du mir denn erklären, wie ich aus den bisher vorhandenen 2 pem-Dateien (oder einfach zusätzlich) die benötigen PKCS12-Datei mit Passwort erstelle? Bzw. wo ich eine gute Anleitung dazu finde?
Siehe Link oben. Das PKCS12-Zertifikat kann auch ohne Passwort erstellt und verwendet werden. Sollte aber eines haben.

Wünsche dir weiterhin viel Spass beim Tüfteln!
Bei Fragen, bitte weiterhin melden.
Schöne Grüße
Egmont

saschko

  • Newbie
  • *
  • Beiträge: 3
  • Gerät: Sony z3 compact
  • Version: 4.4.4
Re: Roter Java-Fehler
« Antwort #4 am: 18.11.2014, 21:48:19 »
Hallo,
wollte mich noch mal kurz melden und für die ausführlichen Informationen bedanken. Ich denke, ich werde das genau so machen --- wenn ich mir einen RPI gekauft habe.

Zur Info noch zur Synology DS107+ (die ich einsetze):
auch aufgrund deiner Hilfe habe ich in der Zwischenzeit rausgefunden, dass auf der Synology tatsächlich ein Apache-Server läuft (genauer: sogar zwei: ein System-Apache und ein User-Apache). Die entsprechenden Pfade für die relevanten conf-Dateien habe ich auch gefunden (das apache-Verzeichnis liegt in /usr/syno/apache).

Leider ist es aber so, dass es einige Apache-Module fehlen und für die DS107+ auch nicht (ohne weiteres) verfügbar sind. Zum Beispiel das für die Anforderung wichtige mod_proxy-Modul. Wie auch immer: ich gebe jetzt auf, bestelle mir einen RPI und mache es dann dort noch mal vernünftig. Wird aber vermutlich noch eine Weile dauern. Deswegen wollte ich mich schon mal kurz melden und bedanken.
Viele Grüße, Sascha