![]() |
Zertifikat nutzen
Hallo,
per TRestClient/TRestRequest greifen wir auf eine Schnittstelle eines Kunden zu, derzeit noch per HTTP. Wenn unser Schnittstellen-Programm produktiv gehen soll, dann soll es aber per HTTPS arbeiten. Dazu stellt uns der Betreiber der Schnittstelle dann ein "Zertifikat" zur Verfügung. Damit habe ich bisher keine Erfahrung. Leider habe ich auch auf mehrfache Anfrage dieses Zertifikat nocht nicht erhalten und kann mir so noch keine Vorstellung davon machen, was das eigentlich genau ist (vermutlich eine Datei, so stelle ich mir das vor). Ich wurde lediglich gefragt, ob wir ein Zertifikat in unsere Anwendung einbinden könnten. Ich wüsste aber nicht wie man in Delphi Seattle ein solches einbindet (irgendwo in den Projektoptionen oder so). Nun bin ich der Spur ![]()
Delphi-Quellcode:
object IdHTTP: TIdHTTP
IOHandler = IdSSLIOHandlerSocketOpenSSL AllowCookies = True ProxyParams.BasicAuthentication = False ProxyParams.ProxyPort = 0 Request.ContentLength = -1 Request.ContentRangeEnd = -1 Request.ContentRangeStart = -1 Request.ContentRangeInstanceLength = -1 Request.Accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' Request.BasicAuthentication = False Request.UserAgent = 'Mozilla/3.0 (compatible; Indy Library)' Request.Ranges.Units = 'bytes' Request.Ranges = <> HTTPOptions = [hoForceEncodeParams] Left = 120 Top = 408 end object IdSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL MaxLineAction = maException Port = 0 DefaultPort = 0 SSLOptions.Mode = sslmUnassigned SSLOptions.VerifyMode = [] SSLOptions.VerifyDepth = 0 Left = 120 Top = 460 end Letztere hat ein Property SSLOptions und darin ein "CertFile"- und ein "RootCertFile"-Property, da könnte ich mir vorstellen, dann ein "Zertifikat", wie ich es erhalten soll, einzutragen. Aber wie verbandel ich das ganze mit dem Rest der Anwendung? Wirklich was erhellendes habe ich im Netz dazu nicht gefunden. Und mit der Indy-Doku komme ich auch nicht klar (viele Links auf der Webseite sind tot), da finde ich kein rudimentäres Beispiel, das die Verwendung von TIdHTTP oder TIdSSLIOHandlerSocketOpenSSL zeigt. Hat jemand ein Beispiel an der Hand wie man mit TIdHTTP/TIdSSLIOHandlerSocketOpenSSL Zertifikate nutzt? Danke. Gruß, Markus |
AW: Zertifikat nutzen
Bei HTTPS liegt das Zertifikat auf dem Webserver. In Delphi braucht man dazu kein Zertifikat zu installieren, da Indy über OpenSSL die HTTPS Verbindung aufbaut.
Für TIdHttp muss auch nicht unbedingt kein TIdSSLIOHandlerSocketOpenSSL im Code erzeugt werden. Indy erzeugt für URLs, die mit https:// beginnen, den TIdSSLIOHandlerSocketOpenSSL selbst. Nur falls es sich um ein "Client-Zertifikat" oder ein Signatur-Zertifikat handeln sollte muss die Delphi Anwendung das Zertifikat lokal haben und z.B. Requests damit signieren. Dazu sollte der Anbieter des Web Service allerdings Informationen haben. |
AW: Zertifikat nutzen
Zitat:
|
AW: Zertifikat nutzen
Und bei einem Server Zertifikat, sollte der public-Teil ebenfalls in der Anwendung vorliegen. Damit kannst du dann die Authentizität des Servers prüfen und dein Programm gegen MITM absichern.
|
AW: Zertifikat nutzen
Zitat:
|
AW: Zertifikat nutzen
[OT]
Nebenbei würde mich interessieren, wie man einen eigenen REST-Server per Let's Encrypt mit einem SSL-Zertifikat ausstattet. Kann man das direkt von der eigenen Anwendung aus? Oder sollte man lieber parallel einen Apache/NGINX-Server auf der Maschine laufen lassen, der sich um die Aktualisierung kümmert? Soweit ich das verstanden habe, legt der Webserver das Zertifikat definiert im System ab und ich kann ich in meine Server-Anwendung herein laden. [/OT] |
AW: Zertifikat nutzen
Gelöscht wegen Doppelpost (entweder ist mein Koffeinspiegel noch zu niedrig oder das Board hatte Schluckauf ^^)
|
AW: Zertifikat nutzen
Moin!
Zitat:
"F: Wie kann ich den Motor meines Autos reparieren? A: In dem Sie die Motorhaube öffnen." Die besagte Anleitung bringt einen bestenfalls da hin, dass man eine verschlüsselte Verbindung aufbaut. Allerdings ist man dann noch längst nicht an dem Punkt wo man sagen kann: Ich weiß dass die Verbindung sicher ist. Denn es wären auch die Zertifikate zu prüfen einschließlich deren CAs. Was mir auch noch größte Bauchschmerzen bereitet ist die Tatsache, dass man für Indy abgewandelte, vorkompilierte OpenSSL-Bibliotheken verwenden muss. Aktueller Stand von OpenSSL ist 1.1.0b während Indy noch bei 0.9.8r steht (eine "r" gibt es noch nicht mal offiziell). Die stammt lt. ![]() Oh oh oh... Grüße Cody EDIT: Korrektur, aktuell steht Indy bei 1.0.2j (August 2016) - mein Fehler :oops: - Die Kritik an der Emba-Anleitung und den modifizierten, nur als Binary erhältlichen OpenSSL-Libs lass ich aber mal so stehen. |
AW: Zertifikat nutzen
Zitat:
Quelle: ![]() |
AW: Zertifikat nutzen
@Zwirbel
Mich hat Indy verwirrt und sprachlos zurückgelassen; von Doku kann nicht wirklich die Rede sein, und im Netz habe ich nur Fragen zum Thema Indy, aber kaum Antworten gefunden. Das ist sehr schade. Ich habe die Geschichte dann ohne Indy gelöst. In ![]() Übrigens werden die Clientzertifikate eigentlich nur in den Zertifikatspeicher importiert (IExplorer) und beim Verbindungsaufbau angegeben (siehe Quellcode). Mein Code funktioniert mit Delphi 2010; die Anwendungen greifen auf Server des Bundesverwaltungsamtes im geschlossenen Deutschland-Online-Netz zu. Gruß Michael |
AW: Zertifikat nutzen
Hallo zusammen,
auch wenn das ursprüngliche Problme gelöst zu sein scheint, möchte ich noch ein paar Punkte anmerken: 1) Als Ergänzung zu mjustin: Assertor stellt compilierte Versionen von OpenSSL (meistens schon kurz nach den offiziellen Erscheinen) zur Verfügung, siehe dazu ![]() 2) Um das Problem mit indy und Openssl zu umgehen, hat Embarcadero mit einer der letzten Delphi-Versionen einen eigenen http-Client eingeführt, der auch für https kein openSSL benötigen und zur Zertifikatsprüfung den Windows CertStore verwenden soll. Damit habe ich aber noch keine Erfahrung, und sollte ich etwas falsches geschrieben haben, bitte ich um Korrektur! |
AW: Zertifikat nutzen
Zitat:
Code:
Letztlich habe ich dann in der Registry einen Eintrag der Art:
-----BEGIN CERTIFICATE-----
[ca. 2700 Zeichen] -----END CERTIFICATE-----
Code:
Die Schnittstelle selbst arbeitet mit den Komponenten „TRestClient“, „TRestRequest“ und „TRestResponse“. Wie gesagt, seit Jahr und Tag per HTTP ohne Probleme.
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\SystemCertificates\addressbook\Certificates\[40 Zeichen]]
"Blob"=hex:[Hex-Werte] Wenn ich jetzt einfach die URL die ich habe, umstelle von:
Code:
auf:
http://1.1.1.1/dings/v1.1
Code:
und dann das „Execute“ des TRESTRequest absetzte erhalte ich:
https://1.1.1.1/dings/v1.1
Code:
Was bedeutet die Fehlermeldung nun konkret? Was ist da „unspezifiziert“?
Modul: REST-Anforderung fehlgeschlagen: Unspecified certificate from client
Erschwerend kommt hinzu, dass ich von meinem Entwicklungsrechner aus per VPN mit der Kundeninfrastruktur verbunden bin. Aus Erfahrung weiß ich, dass es bei einigen Dingen schon einen Unterschied gemacht hat, ob man direkt im entsprechenden Zielnetzwerk unterwegs ist oder eben von „außen“ per VPN kommt. Leider kann mir die Kunden-IT auch nicht wirklich weiter helfen. Es wurde z. B. empfohlen mal mit einer PowerShell eine Abfrage an die Schnittstelle abzusetzen, um sozusagen das prinzipielle Funktionieren des Zertifikates zu testen:
Code:
Das liefert mir aber:
Invoke-WebRequest -Uri "https://1.1.1.1/dings/v1.1" -Certificate 'Cert:\CurrentUser\[40-Zeichen]'
Code:
Da bin ich mit meinem Latein am Ende.
> PS C:\WINDOWS\system32> Invoke-WebRequest -Uri "https://1.1.1.1/dings/v1.1" -Certificate 'Cert:\CurrentUser\[40-Zeichen]'
> Invoke-WebRequest : Der Parameter "Certificate" kann nicht gebunden werden. Der Wert > "Cert:\CurrentUser\[40-Zeichen]" kann nicht in den Typ > "System.Security.Cryptography.X509Certificates.X509Certificate" konvertiert werden. Fehler: "Das angegebene Pfadformat > wird nicht unterstützt." > In Zeile:1 Zeichen:85 > + ... Certificate 'Cert:\CurrentUser\[40-Zeichen] ... > + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException > + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeWebRequestCommand Ich setze noch Delphi 10 Seattle ein. Lässt sich mein Problem durch Umstieg auf die aktuelle Version lösen? Oder kann mir jemand aus eigener Erfahrung bestätigen, dass man, um ein Zertifikat (wie ich es oben beschrieben habe) in seinem eigenen Code zu nutzen gar nichts tun muss? Und das Zertifikat muss einfach auf dem Rechner, auf dem die HTTPS-Abfrage gestellt wird, vorhanden sein? Danke im Voraus für etwas Erhellung. Gruß, Markus |
AW: Zertifikat nutzen
Zitat:
Das Zertifikat des HTTPS Servers kann man auch mit dem Web Browser downloaden und dann mit der CR Datei vergleichen. Sind sie identisch, ist die CR Datei einfach nur das Serverzertifikat. Der Anbieter des Webservice sollte die Frage ob es das Server- oder ein Clientzertifikat ist eigentlich beantworten können. Ich würde daher einfach die "CertFile"- und ein "RootCertFile"-Property leer lassen und einen REST Request ausführen. (Oder den Endpoint im Webbrowser oder per curl aufrufen) |
AW: Zertifikat nutzen
Mir schwant da schon wieder übles... Zertifikate werden normalerweise nicht auf diese Weise verteilt, es sei denn es sind selbst erstellte weil man sich das Brimborium mit den CA sparen wollte.
Die biegt man dann mit viel Verrenkungen in den Zertifikatsspeicher von Windows rein, dreht an den Sicherheitseinstellungen rum bis die Verbindung "irgendwie" läuft und das nächstbeste Windows-Update dreht die Einstellungen wieder zurück. Meistens weil die Zertifikatskette nicht passt oder das Stammzertifikat wiederrufen wurde. Für gewöhnlich stellt der Webserver die Public Keys selbst zur Verfügung und die Komponenten handeln die Verschlüsselung aus. Bei den Indys kann an die Prüftiefe noch einstellen (Zerti-Kette bis zum Stamm prüfen oder nicht), bei den REST-Komponenten geht das schon nicht mehr, weil alles an den Systemeinstellungen hängt. Also kurz gesagt: Vergiss erstmal die Zertifikatsdateien. Schreib einfach statt http:// dann https:// in den URL und schau was passiert. Ggf. noch den Port manuell von 80 auf 443 ändern, mehr sollte eig. nicht nötig sein. |
AW: Zertifikat nutzen
Zitat:
Vielleicht noch mal was zum Hintergrund. Unser Kunde bekommt von der IT-Abteilung dessen Netzwerk und auch Computer er nutzt das Zertifikat geschickt. Unser Kunde schickt das Zertifikat mir. Es fehlen jegliche Anweisungen, was ich a) mit dem Zertifikat machen soll oder b) wie man testen kann dass es funktioniert. Absolut null Info. Frage ich dann bei dieser IT-Abteilung nach, die Ansprechpartner auch für unseren Kunden ist, dann wissen diese Leute von der IT wenig bis nichts zu dem Zertifikat zu sagen. Bisher habe ich in der URL eine IP-Adresse verwendet (was bei HTTP wunderbar funktioniert hat), heute erfahre ich, ich soll den vollen DNS-Namen verwenden. Dann habe ich im OnValidateCertificate des TRestClient das Accepted auf True gesetzt, wie ich es im Netz gefunden hatte, dass man das machen soll. Und schon lautete die Fehlermeldung nicht mehr: REST-Anforderung fehlgeschlagen: Server Certificate not accepted sondern: REST-Anforderung fehlgeschlagen: Unspecified certificate from client Aber es kommt noch doller. Im OnValidateCertificate habe ich mir mal alle zur Verfügung stehenden Infos des „const [Ref] Certificate: TCertificate“ ausgeben lassen. Schön war schon mal, da stand tatsächlich etwas, was mit dem Zertifikat zu tun hatte. Aber, aufgemerkt, da stand nicht die URL drin die ich verwenden sollte, sondern es war noch ein Zeichen anders (zusätzlich) in der URL. Als ich die URL dann so geschrieben habe, wie sie auch im Zertifikat hinterlegt ist, kam keine Fehlermeldung mehr bzgl. des Zertifikats! Daten habe ich aber trotzdem keine Empfangen, Fehlermeldung: REST-Anforderung fehlgeschlagen: Execution of request terminated with unknown error Es wird so sein wie so oft. Diese Test-Schnittstelle ist bei der IT-Abteilung gar nicht scharf geschaltet. Ich warte noch auf Feedback. Ach ja, mein erster Gedanke war auch, ich nehme einfach statt http:// dann ![]() Ich berichte, wenn es was Neues gibt. Gruß, Markus |
AW: Zertifikat nutzen
Oh weh. Grundsätzlich müssen Zertifikat, IP-Adresse und Hostname zusammen passen. Am Ende wird das auf beiden Seiten irgendwie zusammengeschustert. Hauptsache es läuft. Könnte mir vorstellen, so ähnlich ist es zwischen BRAK und ATOS auch gelaufen beim beA. Sicherheit kommt dabei aber mit Sicherheit nicht heraus. Tu dir selbst einen Gefallen und lehn den Auftrag ab.
OT: Weisst warum ich die REST-Komponenten nicht mag und wieder auf Indy zurück gewechselt bin? Weil man ![]() |
AW: Zertifikat nutzen
Zitat:
So wie es aussieht kriege ich das mit dem Zertifikat und den REST-Komponenten nicht gebacken und muss wohl in den sauren Apfel beissen nur deswegen auf Indy umstellen. :shock: |
AW: Zertifikat nutzen
Die REST-Komponenten basieren (bei Win32 und Win64) auf WinInet und "erben" sozusagen diverse Sicherheitseinstellungen aus der Abteilung Internet Explorer. Dort wäre auch der Ansatz, das Zertifikat zumindest testweise einzuspielen. Bevor jetzt alles auf Indy umgestrickt wird.
Ich wollte mit meinen Bedenken nur zum Ausdruck bringen, dass SSL/TLS ja eigentlich erfunden wurde um die Transportsicherheit zu erhöhen. So wie du das beschreibst, bestehen auf beiden Seiten viele Ungewissheiten über die Problematik. Daher befürchte ich, wird das Vorhaben nicht den gewünschten Erfolg bringen. Egal ob nun mit WinInet oder Indy. Möglich, dass es "irgendwann" "irgendwie" läuft. Nur ob das dann auch das Prädikat "gesicherte Verbindung" verdient, steht in den Sternen. |
AW: Zertifikat nutzen
Zitat:
Zitat:
Es ist zum Haareraufen. |
AW: Zertifikat nutzen
Zitat:
Zitat:
Ich würde dir raten, die Insider bei deinem Dienstanbieter zu einem Grillabend einzuladen. Es geht nix über Vitamin B um solche Probleme aus der Welt zu schaffen ;-) |
AW: Zertifikat nutzen
@Zwirbel
Hast Du meinen Code mal getestet? |
AW: Zertifikat nutzen
Zitat:
Aber das würde bedeuten, ich müsste meinen bisherigen Code komplett umwerfen, all die schönen und simplen TRest-Komponenten von Delphi in Zusammenhang mit einem RESTResponseDataSetAdapter, das war ja einfach genial, nach der Datenabfrage marschiert man einfach durch ein DataSet durch, kein Gepfriemel das JSON auseinander zu pflücken etc. In diesem BlogPost: ![]() steht etwas von "New REST Client Events OnNeedClientCert and OnAuthEvent", das liest sich eigentlich genau so, als ob das meine Lösung wäre, einfach in dem OnNeedClientCert das Zertifikat bestimmen und fertig. Leider gibt es mal wieder keine brauchbare Online-Hilfe zu diesem Event. Hier: ![]() steht nur: "It uses the computer's certificate store. Install the certificate, then when OnNeedClientCert fires, you return the index of the certificate from the provided Certificate you want to use." Der Witz ist nur dieser Event feuert bei mir nicht. Der Kommentar eines Nutzers: "Without this feature, the Rest Debugger is useless when you need certificates. Sample code on the doc also would be fine." Dem kann ich nur zustimmen. Es ist frustrierend, dass in Delphi so viele Möglichkeiten schlummern, die man aber mangels vorhandener tauglicher Beispiele in die Praxis nicht umsetzen kann. Die Entwickler die diesen Event "OnNeedClientCert" implementiert haben, die müssen das doch auch mal irgendwie getestet haben. Ist es da zu viel verlangt "einfach" ein paar Code-Schnippsel in die Online-Hilfe zu pappen. So suchen sich hunderte und tausende von Entwicklern dusselig bis sie es sich dann selbst aus den Fingern gesogen haben oder die Sache in die Ecke feuern... Hat jemand hier praktische Erfahrung mit dem Event "TRestClient.OnNeedClientCert"? Danke im Voraus. Gruß, Markus |
AW: Zertifikat nutzen
Zitat:
Ich kann deinen Frust gut verstehen. Wir hatten mit den Restkomponenten derart viele Probleme, dass wir nicht nur ein eigenes REST-HTTPS-Backend auf Basis von Indy gebaut haben sondern sogar noch einen JSON-Parser dazu, der XPath versteht. Dadurch können wir auf der selben Codebasis sowohl JSON, als auch XML und SOAP ansprechen. Warum die neuen Restkomponenten in der Praxis so viele Probleme machen? Weil sie zu sehr auf das Betriebssystem setzen. Da greifen Sicherheitseinstellungen, denen sich die Anwender nicht einmal bewusst sind. Zumal der Großteil dieser Einstellungen unter Windows in der Abteilung Internet Explorer getätigt werden muss - einem abgekündigten Browser, der noch so ca. 4% Marktanteil hat. Insofern würde ich noch nicht einmal Emba einen Vorwurf machen. Kaputtgefrickelt wurde Wininet von Microsoft. Der einzige Fehler von Emba war, überhaupt von Indy auf Wininet umzusteigen. |
AW: Zertifikat nutzen
Um die Sache hier abzuschließen. Das "OnNeedClientCert" funktioniert bei mir nicht. Im Thread "https://quality.embarcadero.com/browse/RSP-15857" wurde mir bestätigt, dass es aber funktioniert. Ich hatte dazu ein kleines Test-Programm geschrieben. Nun wird der Fall wieder untersucht. Mal gespannt, wann es da eine Lösung gibt. Zwischenzeitlich habe ich mir mit den ICS-Komponenten ("ICS - Internet Component Suite - V8 - Delphi 7 to RAD Studio 10.3 Rio") geholfen. Hilfreich ist dabei das Test-Projekt "OverbyteIcsHttpsTst".
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz