Entwickler-Ecke

Netzwerk - Serververbindung über https funktioniert nicht


Csharp-programmierer - Sa 26.11.16 14:58
Titel: Serververbindung über https funktioniert nicht
Hallo Leute,
ich habe meine Website nun über https:// gesichert. Wenn mein Programm nun Serveranfragen an die PHP Scripte sendet, die geschützt sind, kommt dieser Fehler:

Die zugrunde liegende Verbindung wurde geschlossen: Für den geschützten SSL/TLS-Kanal konnte keine Vertrauensstellung hergestellt werden..

Wie kann man diesen Fehler beseitigen?


jaenicke - Sa 26.11.16 16:49

Das kommt ja darauf an wie du die Verbindung herstellst.

Wenn du einen WebRequest verwendest, sollte es reichen den ServerCertificateValidationCallback zu implementieren.


Csharp-programmierer - Sa 26.11.16 16:57

Ich stelle die Serververbindung so her:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
string URL = "https://www.mainlysoft.com/Mainlynet/Administration/Logbuch.php";
                        WebClient webClient = new WebClient();

                        NameValueCollection formData = new NameValueCollection();
                        formData["value1"] = "";
                        formData["value2"] = "";
                        formData["value3"] = "";
                        formData["value4"] = "";

                        byte[] responseBytes = webClient.UploadValues(URL, "POST", formData);
                        string responsefromserver = Encoding.UTF8.GetString(responseBytes);
                        webClient.Dispose();


So baue ich eine Serververbindung auf und empfange die Daten. Wie und wo muss ich jetzt das CallBack hinzufügen?


Th69 - Sa 26.11.16 18:53

s. z.B. Probleme mit Webrequests und SSL [https://u-labs.de/forum/net-94/probleme-mit-webrequests-und-ssl-28545/]


Csharp-programmierer - Sa 26.11.16 20:01

Vielen Dank für den Link.

Ich habe diesen Code jetzt mal ausgeführt, aber es funktioniert nicht


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
                    delegate (object sender1, X509Certificate cert, X509Chain chain, SslPolicyErrors sslError) {
                        bool validationResult = true;
                        return validationResult;
                };

                HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create("https://mainlysoft.com/Mainlynet/Administration/test.php");
                // In der unteren Zeile kommt der Fehler
                myHttpWebRequest.Host = "https://www.alfahosting.de";
                myHttpWebRequest.Method = "POST";
                CookieContainer cc = new CookieContainer();
                myHttpWebRequest.CookieContainer = cc;

                myHttpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0";
                myHttpWebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
        
                byte[] data = Encoding.ASCII.GetBytes(this.textBox1.Text);
                myHttpWebRequest.ContentLength = data.Length;

                Stream requestStream = myHttpWebRequest.GetRequestStream();
                requestStream.Write(data, 0, data.Length);
                requestStream.Close();

                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

                Stream responseStream = myHttpWebResponse.GetResponseStream();

                StreamReader myStreamReader = new StreamReader(responseStream, Encoding.Default);

                string pageContent = myStreamReader.ReadToEnd();

                myStreamReader.Close();
                responseStream.Close();

                myHttpWebResponse.Close();

                MessageBox.Show(pageContent);


Aber in dem Forum stand auch, dass es unsicher ist. In wie weit??

PS: Ich habe schon versucht die Daten über die GET Variable mirzuliefern. Das funktioniert soweit, aber ich vertraue $_GET nicht so, was meint ihr dazu?


Ralf Jansen - So 27.11.16 13:40

Der Callback liefert dir die Fehler mit. Schau doch einfach in sslError nach was das Problem ist.

Zitat:
In wie weit??


Eine rethorische Frage? In einem Callback in dem du das Zertifikat prüfen solltest sagst du einfach immer das Zertifikat ist ok. Und du fragst dich wo das den unsicher sein könnte?


Csharp-programmierer - So 27.11.16 14:31

Ich habe mich auch schon gewandert, warum diese delegate immer true returned, aber auf dem Link war das so als Beispiel :/


Csharp-programmierer - So 27.11.16 16:07

Ich habe mir den Wert von der sslError Variable ausgeben lassen. Es hat sich keine MessageBox geöffnet, also tippe ich mal darauf, dass der Server kein Zertifikat rausgibt. Der Fehler kommt nun in der Host Zeile, welchen Host muss ich da angeben? In dem Rechenzentrum, wo der Server steht, oder die Domain meiner Website?


Th69 - So 27.11.16 17:11

Laß mal das "https://" beim Host weg.


Csharp-programmierer - So 27.11.16 18:54

Vielen Dank :)

Jetzt bekomme ich den Fehler des Zertifikats: RemoteCertificateNameMismatch und das Programm schlägt in dieser Zeile Alarm: HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

Wie kann man das Problem nun beseitigen?

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Csharp-programmierer - Mo 28.11.16 19:44

Hallo forum, könnt ihr mit bitte helfen? Ich hab überhaupt keinen Plan, wie ich den Fehler beheben soll:(


Christian S. - Mo 28.11.16 20:46

Setze den Host einfach mal gar nicht.


Csharp-programmierer - Mo 28.11.16 21:10

Okay vielen Dank für die Antwort. Ich habe die Zeile mit dem Host rausgelöscht. Jetzt gibt die sslError Variable folgendes raus: none. Wie kann das jetzt sein?


Ralf Jansen - Mo 28.11.16 21:21

None = Kein Fehler.


Csharp-programmierer - Mo 28.11.16 21:49

Stimmt. Aber wie gebe ich der Methode einen Wert mit? Früher habe ich es ja über die NameValueCollection gemacht. Jetzt muss man dem Programm ja sagen, dass die POST Variable ["value"] = "Hallo" sein soll. Wie macht man das?

EDIT: Ich habe auf dem PHP Script jetzt einfach den Wert "Hallo vom Server" geechoed. Das zeigt mir das C# Programm auch, also funktioniert die Verbindung ja jetzt schon. Jetzt liegt es nur an dem String, der die Daten zum Server hinsendet.
Ist das jetzt auch gesichert, weil das Zertifikat ist ja jetzt none?


Ralf Jansen - Di 29.11.16 11:30

Zitat:
Ist das jetzt auch gesichert, weil das Zertifikat ist ja jetzt none?

Sollte.
Zitat:
Stimmt. Aber wie gebe ich der Methode einen Wert mit? Früher habe ich es ja über die NameValueCollection gemacht.

Du kannst weiter eine NamedValueCollection(genauer eine Ableitung davon) benutzen um die zu postenden Daten passend zu formatieren.

C#-Quelltext
1:
2:
3:
4:
NameValueCollection nvc = HttpUtility.ParseQueryString(String.Empty);
nvc.Add("Value1", MeinLieberValue1);
nvc.Add("Value2", MeinLieberValue1);
byte[] data = Encoding.ASCII.GetBytes(nvc.ToString();


Csharp-programmierer - Di 29.11.16 14:15

Und was ist dann HttpUtility? Sonst würde ein Fehler kommen, ob eine Using Methode oder ein Assemblyverweis vergessen wurde. Jetzt erkennt er HttpUtility nicht :(

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Christian S. - Di 29.11.16 14:18

https://lmgtfy.com/?q=HttpUtility


Csharp-programmierer - Mi 30.11.16 07:44

Boar vielen Dank, jetzt funktioniert es :))


Csharp-programmierer - Mi 30.11.16 16:44

Ich habe jetzt mal eine Frage. Ich habe in dem Admin Programm einmal diese Methode ausgeführt, wie es hier beschrieben wurde. Jetzt auf einmal funktionieren auch die anderen Funktionen, die das Zertifikat nicht abfangen. Ist das so normal? Die URLs fangen alle mit https:// an??
Das Programm besteht aus einem Fenster1, in dem man sich einloggt. Alle übergeordneten Funktionen, die nichts mit der Form1 zu tun haben funktionieren auf einmal?


Ralf Jansen - Mi 30.11.16 23:43

Der ServicePointManager.ServerCertificateValidationCallback ist eine globale Sache der hat nix mit dem HttpWebRequest den du ~zufällig~ direkt daneben programmiert hast.
Der Callback ist statisch und zieht für alle Requests. Wen du den Callback also später für andere Requests nicht mehr willst dann musst du ServerCertificateValidationCallback anschließend null zuweisen.


Csharp-programmierer - Do 01.12.16 09:27

Ich habe ja 2 unterschiedliche Methoden, Daten an eine PHP Datei zu senden:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create("https://meineURL.com/Script.php");
                myHttpWebRequest.Method = "POST";

                myHttpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0";
                myHttpWebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";

                NameValueCollection nv = HttpUtility.ParseQueryString(String.Empty);
                nv["value"] = this.textBox1.Text;
                byte[] data = Encoding.ASCII.GetBytes(nv.ToString());
                myHttpWebRequest.ContentLength = data.Length;

                Stream requestStream = myHttpWebRequest.GetRequestStream();
                requestStream.Write(data, 0, data.Length);
                requestStream.Close();

                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                Stream responseStream = myHttpWebResponse.GetResponseStream();
                StreamReader myStreamReader = new StreamReader(responseStream, Encoding.Default);

                string pageContent = myStreamReader.ReadToEnd();

                myStreamReader.Close();
                responseStream.Close();
                myHttpWebResponse.Close();

                MessageBox.Show(pageContent, "Page Content");



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
string URL = @"https://meineURL/Script.php";
            WebClient webClient = new WebClient();

            NameValueCollection formData = new NameValueCollection();
            formData["value"] = this.textBox1.Text;

            byte[] responseBytes = webClient.UploadValues(URL, "POST", formData);
            string responsefromserver = Encoding.UTF8.GetString(responseBytes);
            webClient.Dispose();
            MessageBox.Show(responsefromserver);


Der Grund, warum ich den Thread eröffnet habe war, dass bei der zweiten Methode der Fehler kam, dass die Verbindung aufgrund einer Unsicherheit geschlossen wurde. Ich habe aus Spaß jetzt ein kleines Programm geschrieben, was diese beiden Methoden enthält. Mit Button1 wird die obere Methode ausgeführt und mit Button2 die untere. Beide funktionieren jetzt. Aber warum? Ich meine es gab ja anfangs Probleme?

Hier sind die Bilder von Charles, der die Datenpakete abfängt:
1
2


Csharp-programmierer - Fr 02.12.16 21:29

Und welche der beiden Methoden ist sicherer?