Bagaimana cara menggunakan WebRequest untuk mengakses situs terenkripsi SSL menggunakan https?

116

Saya sedang menulis program yang membaca konten dari URL yang disediakan pengguna. Masalah saya ada pada kode yang berbunyi seperti ini:

Uri uri = new Uri(url);
WebRequest webRequest = WebRequest.Create(uri);
WebResponse webResponse = webRequest.GetResponse();
ReadFrom(webResponse.GetResponseStream());

Dan ini rusak jika url yang diberikan adalah URL "https: //". Adakah yang bisa membantu saya dengan mengubah kode ini sehingga akan bekerja dengan konten terenkripsi SSL. Terima kasih.

Alfred B. Thordarson
sumber

Jawaban:

175

Anda melakukannya dengan cara yang benar, tetapi pengguna mungkin memberikan url ke situs yang memasang sertifikat SSL yang tidak valid. Anda dapat mengabaikan masalah sertifikat tersebut jika Anda memasukkan baris ini sebelum membuat permintaan web yang sebenarnya:

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

dimana AcceptAllCertificationsdidefinisikan sebagai

public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}
LukeDuff
sumber
41
Terima kasih atas jawaban ini! Untuk menghindari beberapa kode yang tidak berguna saya menggunakannya seperti ini: ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
Charles Ouellet
4
Terima kasih, Anda membantu saya Pak. F # membuatnya lebih mudah:ServicePointManager.ServerCertificateValidationCallback <- Security.RemoteCertificateValidationCallback (fun _ _ _ _ -> true)
David Grenier
2
@Charles Ouellet Saya rasa saya bahkan lebih malas dari Anda, (a, b, c, d) => true
Despertar
24
Saya lebih suka+= delegate { return true; }
vkrzv
2
Waspadai potensi risiko yang terkait dengan pendekatan ini. Lihat stackoverflow.com/a/6613434/2969615 untuk informasi lebih lanjut.
Joe Coyle
19

Tautan ini akan menarik bagi Anda: http://msdn.microsoft.com/en-us/library/ds8bxk2a.aspx

Untuk koneksi http, kelas WebRequest dan WebResponse menggunakan SSL untuk berkomunikasi dengan host web yang mendukung SSL. Keputusan untuk menggunakan SSL dibuat oleh kelas WebRequest, berdasarkan URI yang diberikan. Jika URI dimulai dengan "https:", SSL digunakan; jika URI dimulai dengan "http:", koneksi tidak terenkripsi digunakan.

GurdeepS
sumber
Tautan bagus. Itu perbedaan penting.
DanM7
1
Jawaban Anda menyiratkan kode dalam pertanyaan itu harus berfungsi?
Rowland Shaw
18

Yang ini berhasil untuk saya:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Nani
sumber
1
Nilai defaultnya adalah "Ssl2 | Tls". Saya hanya mengaktifkan Tls 1.1 dan 1.2 di server saya. Ini memang memperbaiki masalah! Untuk LetsEncrypt dengan nginX di linux, protokolnya didefinisikan di sini: /etc/letsencrypt/options-ssl-nginx.conf
Jerther
Saya yakin ini berurusan dengan masalah yang berbeda. Ini bukan tentang Sertifikat yang tidak valid tetapi versi TLS yang lebih tinggi.
wp78de
Saya mendapatkan "Sambungan yang ada ditutup secara paksa oleh host jarak jauh" dan solusi ini berhasil untuk saya
oamilkar
Perhatikan bahwa ini adalah konfigurasi global, jadi Anda hanya perlu melakukannya sekali dan tidak setiap kali Anda menyiapkan permintaan.
Chad Hedgcock
Dapatkah saya melakukan ini untuk satu permintaan? Sepertinya ServicePointManager adalah hal yang agak global ...
wexman