C# ile bir HTTP(S) isteği göndermeye çalıştığınızda aşağıdaki gibi bir hata alabilirsiniz:
System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
Bu hata, istemci (yani sizin uygulamanız) ile hedef sunucu arasında güvenli bir bağlantı (SSL/TLS) kurulamadığını ifade eder. Bu tür bir hata, özellikle sunucular artık daha eski protokolleri (örneğin SSL 3.0) desteklememeye başladığında sıkça görülür.
Bunun teknik nedenlerini, çözüm yollarını, ve ilgili kavramların (TLS, ServicePointManager, Expect100Continue vb.) ne anlama geldiğini inceleyelim.
En popüler service hatası: SSL/TLS protokol uyumsuzluğu
Bu hata, istemcinin desteklediği SSL/TLS protokol sürümünün, sunucunun desteklediğiyle uyumsuz olması durumunda ortaya çıkar. Mesela uygulamanız sadece SSL3 gönderiyor olabilir fakat karşı sunucu artık sadece TLS 1.2 ve üstünü kabul ediyor olabilir (günümüzde bu çok yaygındır). Dolayısıyla bağlantı kurulamaz ve “secure channel” oluşturulamaz.
Uygulamanızın hedeflediği .NET versiyonu eski olabilir ama bu düşük ihtimaldir (örneğin .NET Framework 4.0 öncesinde TLS 1.2 desteği yoktur). Diğer yandan istek yapmadan önce ServicePointManager.SecurityProtocol ayarı yapılmamıştır ve varsayılan protokol desteklenmiyor olabilir.
Çözüm oldukça basit, istek yapmadan önce bunu çalıştırın:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
TLS (Transport Layer Security), internet üzerindeki veri iletimini şifreleyen ve güvenli hale getiren bir kriptografik protokoldür. TLS 1.2 günümüzde en yaygın desteklenen sürümdür. TLS 1.3 en yenisi ve en güvenlisidir.
.NET’te ServicePointManager.SecurityProtocol ile hangi protokolü kullanacağınızı belirtirsiniz. Birden fazla protokolü bir arada göndermek için bitwise OR kullanabilirsiniz:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls13;
ServicePointManager nedir?
System.Net.ServicePointManager, .NET uygulamalarında HTTP bağlantılarının nasıl yönetileceğini kontrol eden bir sınıftır. TLS/SSL protokol ayarları, connection pool yönetimi, bekleme süresi (timeout) ayarları ve sertifika doğrulama işlemleri için kullanılır.
Expect100Continue nedir?
HTTP 1.1 ile birlikte gelen Expect: 100-Continue başlığı, büyük veri gönderimlerinde istek yapmadan önce sunucudan onay beklemek için kullanılır. İstemci, özellikle büyük POST istekleri göndermeden önce sunucudan 100 Continue yanıtını bekler. Eğer sunucu hemen 4xx gibi bir hata dönecekse, istemci boşuna veri göndermemiş olur. HTTPS ve büyük veri olan body POST/PUT işlemlerinde genellikle true yapılır. Bazı sunucular bunu bekler.
Güncel bir uygulama yapalım:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.example.com");
request.Method = "GET";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string result = reader.ReadToEnd();
Console.WriteLine(result);
}
}
Şimdi burada bir soru doğuyor. Bu config neden global tanımlanıyor, işlem bazlı tanımlanamaz mı? ServicePointManager ayarları globaldir. Alternatif olarak HttpClientHandler ile modern HttpClient kullanımında TLS protokolü ayarlarını metod bazlı yapabilirsiniz.
var handler = new HttpClientHandler();
handler.SslProtocols = SslProtocols.Tls12;
var client = new HttpClient(handler);
Kısacası bu hatayı alıyorsunuz çünkü nasıl istek yapmanız gerektiğini yapılandırmamışsınız. Umarım konu anlaşılmıştır.
Yorum bırakın