Hallo nochmals!
Vor wenigen Tagen hatte ich hier im Forum folgende Frage gestellt:
Eigene DLL: Fehler in PostAsync, wenn DLL von Gupta genutzt wird: "kein geschützter SSL/TLS-Kanal"
Daraufhin erhielt ich einige wertvolle Tipps, für die ich mich bei allen erneut bedanken möchte.
Um den Tipps nachzugehen, habe ich eine einfache Testumgebung aufgebaut, bei der nur Visual Studio (C++, C++/CLR und C#) eine Rolle spielt – das gesamte Gupta-Gedöns habe ich außen vor gelassen.
Nun zum Problem: Wie bereits im letzten Beitrag erwähnt, habe ich eine C#-DLL entwickelt, mit der ich auf einen Webservice über REST zugreife. Bisher funktionierte sie tadellos, wenn ich sie in andere C#-Projekte einbinde. Wenn ich die DLL in Gupta einbinde, löst der Aufruf von
var response = await client.PostAsync(URL, Body);
folgende Ausnahme aus:> Fehlermeldung:
bei System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
bei System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) bei System.Threading.Tasks.Task
1.get_Result()
bei isential.paypal.PayPal..ctor(String AuthenticationFile, String Id)
bei CSharpDll.CSharpClass.PayPalGetPaymentInstruction(String AccessDataFile, String TransactionId, String& PaymentInstruction)
System.Net.Http.HttpRequestException: Fehler beim Senden der Anforderung. ---> System.Net.WebException: Die Anfrage wurde abgebrochen: Es konnte kein geschützter SSL/TLS-Kanal erstellt werden..
bei System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
bei System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bei isential.paypal.PayPal.<GetToken>d__5.MoveNext()
LaTino schrieb mir:
Ich würde eher darauf tippen, dass der Wrapper, der von Gupta benutzt wird, um die .NET-dll aufzurufen, so alt ist, dass er TLS nicht in der Version kennt, die das Gegenüber benutzen möchte. (...)
(...) TD 6.2 unterstützt laut
> nur .NET 4.0 und damit keine neuere TLS-Version. (...)
Nun wollte ich diese Aussage bestätigen, indem ich folgende Testkulisse aufgebaut habe, bei der Gupta komplett außen vor bleibt:1.Konsole-Anwendung in C++ (pur, kein /clr oder sonstiges Gedöns – ersetzt in diesem Test Gupta ). Diese Konsole-Anwendung bindet eine weitere unverwaltete DLL ein. 1.Diese weitere unverwaltete DLL ist ebenfalls in C++ pur geschrieben und soll die von Gupta eingebundene DLL darstellen. Sie bindet eine weitere DLL ein, die in C++/CLR geschrieben ist. 1.Die C++/CLR-DLL ist das Bindeglied zwischen beiden Welten. Sie bindet unsere in C# geschriebenen DLLs ein, welche schlussendlich die Arbeit machen.
Alle verwalteten Komponenten haben als Ziel das Framework 4.7.1 und dennoch wird dieselbe Ausnahme wie bei unseren Versuchen mit Gupta geworfen: > Fehlermeldung:
System.Net.Http.HttpRequestException: Fehler beim Senden der Anforderung. ---> System.Net.WebException: Die Anfrage wurde abgebrochen: Es konnte kein geschützter SSL/TLS-Kanal erstellt werden..
Binde ich die DLL in ein C#-Projekt ein, funktioniert sie tadellos und fehlerfrei.
Andere in C# geschriebene und für den Aufruf aus unverwaltetem Code freigegebene Methoden funktionieren dagegen fehlerfrei. Nur Requests über "HttpClient" verursachen diese SSL/TLS-Fehler.
Jetzt gehen mir die Ideen aus. Hat jemand von euch eine Erklärung dafür?
Im Voraus vielen Dank!
René
Schau dir den TLS Handshake im Fiddler an.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
Ich sehe kein Grund, wieso hier ein neuer Thread erstellt werden muss; aber Gnade und Recht und so....
Meines Wissens reicht es nicht, dass man nur das neuere .NET Framework verwendet.
Sofern die Software auf älteren Systemen als Windows 10 verwendet wird, muss aktiv
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
gesetzt werden, denn der default Type des Protokolls setzt das Betriebssystem - und .NET verwendet dann das default gesetzte.
Und wenn man vor .NET 4.5 arbeitet, dann funktioniert das ebenso, jedoch mit
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
PS: Du bist Entwickler. Du tust Dir keinen Gefallen, wenn Du mit lokalisierten Exception Messages arbeitest.
Arbeite mit einem englischen System und oh Wunder Du wirst sehr viel mehr Treffer bei Exception-Recherchen bekommen; in diesem Fall> Fehlermeldung:
The request was aborted: Could not create SSL/TLS secure channel
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Dankeschön! Ich kannte das Tool bis dato nicht. Für die Untersuchung von https musste ich das Zertifikat von Fiddler installieren – Vertauen ist alles 😃
Beim ersten Anmeldeversuch (POST) bekam ich nachfolgende zwei Logs:
CONNECT api.paypal.com:443 HTTP/1.1
Host: api.paypal.com
Connection: Keep-Alive
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.
Version: 3.1 (TLS/1.0)
Random: 5B FD 66 7B FB 68 33 DB D7 2A F1 A1 1A DE 0B 82 AE 81 51 37 FC B2 25 97 95 E1 7B CD BD 73 BC 0D
"Time": 10.08.2035 10:24:59
SessionID: empty
Extensions:
server_name api.paypal.com
elliptic_curves unknown [0x1D), secp256r1 [0x17], secp384r1 [0x18]
ec_point_formats uncompressed [0x0]
SessionTicket empty
extended_master_secret empty
renegotiation_info 00
Ciphers:
[C00A] TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
[C009] TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
[C014] TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
[C013] TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
[0035] TLS_RSA_AES_256_SHA
[002F] TLS_RSA_AES_128_SHA
[000A] SSL_RSA_WITH_3DES_EDE_SHA
Compression:
[00] NO_COMPRESSION
________________________
fiddler.network.https> HTTPS handshake to api.paypal.com (for #1) failed. System.Security.Authentication.AuthenticationException Fehler bei SSPI-Aufruf, siehe interne Ausnahme. < Das Format der empfangenen Nachricht war unerwartet oder fehlerhaft
Win32 (SChannel) Native Error Code: 0x80090326
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.
Version: 3.1 (TLS/1.0)
Random: 5B FD 66 7C 81 2E 6D B8 88 B2 1C 9B 3E BC 43 8B 9B DA 52 B0 AA 2B C4 BB EC 1E EF AC A2 74 2C 2A
"Time": 20.02.2036 13:45:15
SessionID: empty
Extensions:
server_name api.paypal.com
elliptic_curves unknown [0x1D), secp256r1 [0x17], secp384r1 [0x18]
ec_point_formats uncompressed [0x0]
SessionTicket empty
extended_master_secret empty
renegotiation_info 00
Ciphers:
[C00A] TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
[C009] TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
[C014] TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
[C013] TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
[0035] TLS_RSA_AES_256_SHA
[002F] TLS_RSA_AES_128_SHA
[000A] SSL_RSA_WITH_3DES_EDE_SHA
Compression:
[00] NO_COMPRESSION
________________________
fiddler.network.https> HTTPS handshake to api.paypal.com (for #2) failed. System.Security.Authentication.AuthenticationException Fehler bei SSPI-Aufruf, siehe interne Ausnahme. < Das Format der empfangenen Nachricht war unerwartet oder fehlerhaft
Win32 (SChannel) Native Error Code: 0x80090326
Ich weiß aber nicht, was mir diese Logs sagen wollen. An dieser Stelle muss ich mich als unwissend outen – damit hatte ich bisher keine Berührungen. Ich verstehe das so, dass Fiddler bzw. mein POST den Endpunkt api.paypal.com gar nicht erreicht.
Wenn ich denselben Code (die gleiche DLL) in ein C#-Programm einbinde, funktioniert alles – auf demselben Rechner und auch auch über Fiddler. Ich verstehe das einfach nicht. Ich glaube, ich muss erst darüber schlafen, denn ich bin etwas genervt...
René
Ich kann mit dem Fiddler Output auch nicht viel anfangen; aber da steht was von TLS 1.0 bzw. SSLv3 - ich glaube beides wird von PayPal nicht mehr unterstützt.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Meines Wissens reicht es nicht, dass man nur das neuere .NET Framework verwendet.
Sofern die Software auf älteren Systemen als Windows 10 verwendet wird, muss aktivServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
gesetzt werden, denn der default Type des Protokolls setzt das Betriebssystem - und .NET verwendet dann das default gesetzte.
Es spielt sich alles auf demselben Rechner im selben Code ab. Nur der Weg bis dahin ist ein anderer. Danke auf jeden Fall für die Codezeilen – ich schaue sie mir gleich an.
Und wenn man vor .NET 4.5 arbeitet, dann funktioniert das ebenso, jedoch mit
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
PS: Du bist Entwickler. Du tust Dir keinen Gefallen, wenn Du mit lokalisierten Exception Messages arbeitest.
Arbeite mit einem englischen System und oh Wunder Du wirst sehr viel mehr Treffer bei Exception-Recherchen bekommen; in diesem Fall> Fehlermeldung:
The request was aborted: Could not create SSL/TLS secure channel
Mache ich nicht. Einen Fehler schnell übersetzen und Google und Konsorten damit füttern reicht heute vollkommen aus. Neben Englisch spreche ich auch fließend Spanisch – mit drei Sprachen findet man schon viele Infos, aber hier musste ich passen. ¿Comprendes? 😃
Ich kann mit dem Fiddler Output auch nicht viel anfangen; aber da steht was von TLS 1.0 bzw. SSLv3 - ich glaube beides wird von PayPal nicht mehr unterstützt.
Jo, aber warum auf dem gleichen PC mit demselben Code...? Zur Veranschaulichung:
SSL/TLS geht:
C#-Progrram –– C#-DLL
SSL/TLS geht im Testszenario NICHT:
C-Programm –– C-DLL –– C++-/CLR –– C#-DLL
Ansonsten funktionieren alle andern Methoden.
René
Darum gehts auch in keinster Weise.. Du hast doch schon ein Thread zu exakt diesem Thema erstellt - verwende den doch einfach das nächste Mal einfach weiter 🤔
SSL/TLS geht:
C#-Progrram –– C#-DLLSSL/TLS geht im Testszenario NICHT:
C-Programm –– C-DLL –– C++-/CLR –– C#-DLL
Und wo ist nun die Differenz im Fiddler zwischen "geht" und "geht nicht" ?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Und wo ist nun die Differenz im Fiddler zwischen "geht" und "geht nicht" ?
grant_type=client_credentials
POST /v1/oauth2/token HTTP/1.1
- Accept: application/json
- Accept-Language: en_US
- cache-control: no-cache
- Authorization: Basic unkenntlich_gemacht
- Content-Type: application/x-www-form-urlencoded
- Host: api.paypal.com
- Content-Length: 29
- Expect: 100-continue
- Connection: Keep-Alive
JSON
- access_token=unkenntlich_gemacht
- app_id=APP-unkenntlich_gemacht
- nonce=2018-11-27T17:04:36Z-unkenntlich_gemacht
- scope=https://api.paypal.com/v1/payments/.* [URL]https://uri.paypal.com/services/payments/refund[/URL] [URL]https://uri.paypal.com/services/applications/webhooks[/URL] [URL]https://uri.paypal.com/services/payments/payment/authcapture[/URL] [URL]https://uri.paypal.com/payments/payouts[/URL] [URL]https://api.paypal.com/v1/vault/credit-card/.*[/URL] [URL]https://uri.paypal.com/services/reporting/search/read[/URL] [URL]https://uri.paypal.com/services/disputes/read-seller[/URL] [URL]https://uri.paypal.com/services/subscriptions[/URL] [URL]https://uri.paypal.com/services/disputes/read-buyer[/URL] [URL]https://api.paypal.com/v1/vault/credit-card[/URL] openid [URL]https://uri.paypal.com/services/disputes/update-seller[/URL] [URL]https://uri.paypal.com/services/payments/realtimepayment[/URL]
- token_type=Bearer
Also genau das, was ich nach dem ersten Post erwarte.
Die nachfolgenden Abfragen mit GET funktionieren auch erwartungsgemäß – möchte aber diese JSON-Ergebnisse nicht posten, da diese sehr lang sind und viele Infos beinhalten, die nichts in der Öffentlichkeit verloren haben.
Ich schaue mir noch die statische Klasse "ServicePointManager" genau an. Das war ein hoffentlich guter Tipp, denn ich vermute, dass, wenn ich von der unmanaged Seite herkomme, andere Standardeinstellungen gelten, die mir dann den Spaß vermasseln.
Nochmals vielen Dank!
René
Mh?! Das ist doch nur das HTTP Result und nicht der TLS Handshake.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Mh?! Das ist doch nur das HTTP Result und nicht der TLS Handshake. Ja, hast du Recht, aber dank deiner Hilfe ist eine weitere Untersuchung nicht mehr notwendig. "ServicePointManager" war der Bringer
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Und nun tut es aus allen Richtungen.
Vielen Dank!
René
Darauf wollte ich hinaus, weil ich im Ggs zu Abt die von Paypal verwendete TLS-Version nicht wusste. Nebenbei: ja, dem Zertifikat von Telerik kann man wohl vertrauen 😃.
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
Nochmals Danke an euch beiden, LaTino und Abt! Damit ist dieser Thread gelöst sowie auch Eigene DLL: Fehler in PostAsync, wenn DLL von Gupta genutzt wird: "kein geschützter SSL/TLS-Kanal" – der Grund hier ist derselbe.
Einen schönen Tag und muchas gracias...
René
Hallo pollito,
ich bin hier neu, und auch in der c#-Umgebung, komme von MSAccess mit VBA.
Nun soll ich die Prüfung der USTID über die Schnittstelle evatrRPC(UstId_1, UstId_2, Firmenname, Ort, PLZ, Strasse, Druck) in c# programmieren.
Kannst du mir da evtl. etwas zur Verfügung stellen?
lg und vielen Dank im Voraus
Ich kenne die Schnittstelle nicht. Normalerweise gibt es aber genügend Beispiele zu solchen Schnittstellen, um selbst diese ansprechen zu können.
Grüße
René