Không thể tạo kênh bảo mật SSL / TLS, mặc dù đã đặt ServerCertificateValidationCallback


83

Tôi đang cố gắng thiết lập kết nối SSL / TLS để kiểm tra máy chủ có chứng chỉ tự ký . Giao tiếp thông qua kênh không an toàn đã hoạt động mà không có vấn đề gì.

Đây là mã mẫu của tôi, mà tôi đã viết dựa trên các giải pháp này: Cho phép chứng chỉ SSL không đáng tin cậy với HttpClient C # Bỏ qua lỗi chứng chỉ? Ứng dụng khách .NET kết nối với API Web ssl

ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

var c = new HttpClient();
var r = c.GetAsync("https://10.3.0.1:8443/rest/v1").Result;
if (r.IsSuccessStatusCode)
{
    Log.AddMessage(r.Content.Get<string>());
}
else
{
    Log.AddMessage(string.Format("{0} ({1})", (int)r.StatusCode, r.ReasonPhrase));
}

cũng đã thử điều này:

var handler = new WebRequestHandler();
handler.ServerCertificateValidationCallback = delegate { return true; };
var c = new HttpClient(handler);
...

và điều này

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

nhưng mỗi lần tôi có một ngoại lệ:

InnerException: System.Net.Http.HttpRequestException
   _HResult=-2146233088
   _message=An error occurred while sending the request.
   HResult=-2146233088
   IsTransient=false
   Message=An error occurred while sending the request.
   InnerException: System.Net.WebException
        _HResult=-2146233079
        _message=The request was aborted: Could not create SSL/TLS secure channel.
        HResult=-2146233079
        IsTransient=false
        Message=The request was aborted: Could not create SSL/TLS secure channel.
        Source=System
        StackTrace:
             at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
             at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
        InnerException: 

Tôi làm gì sai? Tại sao tôi không thể kết nối với máy chủ này (có chứng chỉ tự ký không hợp lệ)

Câu trả lời:


161

Bạn đang làm đúng với ServerCertificateValidationCallback. Đây không phải là vấn đề bạn đang gặp phải. Vấn đề bạn đang gặp phải rất có thể là phiên bản của giao thức SSL / TLS.

Ví dụ: nếu máy chủ của bạn chỉ cung cấp SSLv3 và TLSv10 và máy khách của bạn cần TLSv12 thì bạn sẽ nhận được thông báo lỗi này. Điều bạn cần làm là đảm bảo rằng cả máy khách và máy chủ đều được hỗ trợ phiên bản giao thức chung.

Khi tôi cần một ứng dụng khách có thể kết nối với nhiều máy chủ nhất có thể (thay vì an toàn nhất có thể), tôi sử dụng điều này (cùng với việc đặt lệnh gọi lại xác thực):

  ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

1
Tôi có một vấn đề tương tự. Do cuộc tấn công POODLE, chúng tôi buộc phải đóng TLS 1.0 trên máy chủ của mình. Khi tôi làm điều này, ứng dụng của bên thứ ba sẽ ngừng hoạt động. Việc giải mã assambly sẽ hiển thị một mã tương tự như mã của bạn. Nó sử dụng webclientc.SendAsync thay vì GetAsync. Nếu tôi sao chép mã vào ứng dụng console để kiểm tra, tôi có thể tạo lại lỗi và bằng cách thêm ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11, nó sẽ hoạt động. Tôi nghĩ rằng sẽ có một số kiểu bắt tay giữa máy chủ và máy khách để khám phá phiên bản TLS nào sẽ sử dụng? Tại sao nó không tự động chọn 1.1 khi 1.0 bị tắt?
Engern

3
Cảm ơn! Đã đấu tranh 3 giờ với điều này. Thêm dòng này đã làm điều đó cho tôi:ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Thomas T

1
Lưu ý rằng phiên bản mới hơn của NET đã này được kích hoạt theo mặc định, tất cả chúng ta cần phải làm là để thiết lập phiên bản .NET để 4.6.1
martinh_kentico

1
Nó có nghĩa là chính xác, hợp lệ hay không, bạn không quan tâm. Lệnh gọi lại đó cho phép bạn chỉ cần tránh bất kỳ kiểm tra bảo mật nào trên chứng chỉ đó.
Wapac

1
Câu trả lời tuyệt vời, tôi cảm thấy như ServicePointManager.SecurityProtocolgiá trị này có thể là giá trị mặc định. Hoặc ít nhất là phải có thêm thông tin chi tiết trực tiếp bên trong Exception được ném.
Chad

28

Hôm nay chúng tôi đã giải quyết vấn đề tương tự và tất cả những gì bạn cần làm là tăng phiên bản thời gian chạy của .NET

4.5.2 không hoạt động với chúng tôi với sự cố trên, trong khi 4.6.1 vẫn ổn

Nếu bạn cần giữ phiên bản .NET, thì hãy đặt

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

1
Bạn đã sử dụng biến thể nào và chính xác như thế nào?
martinh_kentico

1
Tôi có một ứng dụng .NET 4.5 bắt đầu từ hôm nay, sẽ không hoạt động với một trang web SSL cụ thể. Nếu tôi thay đổi thành 4.6.1, nó hoạt động tốt, nhưng tôi thực sự không thể thay đổi. Tôi không chắc phải làm gì: |
Tsury

16

Cũng giống như một bản theo dõi cho bất kỳ ai vẫn gặp phải vấn đề này - tôi đã thêm các tùy chọn ServicePointManager.SecurityProfile như đã lưu ý trong giải pháp:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Tuy nhiên, tôi vẫn tiếp tục nhận được lỗi “Yêu cầu đã bị hủy bỏ: Không thể tạo kênh bảo mật SSL / TLS”. Tôi đã cố gắng kết nối với một số máy chủ thoại cũ hơn có giao diện HTTPS SOAP API (tức là thư thoại, hệ thống điện thoại IP, v.v. được cài đặt cách đây nhiều năm). Những kết nối này chỉ hỗ trợ kết nối SSL3 vì chúng được cập nhật lần cuối cách đây nhiều năm.

Người ta sẽ nghĩ rằng bao gồm SSl3 trong danh sách SecurityProtocols sẽ thực hiện thủ thuật ở đây, nhưng nó đã không. Cách duy nhất tôi có thể buộc kết nối là CHỈ bao gồm giao thức Ssl3 và không bao gồm các giao thức khác:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

Sau đó, kết nối đi qua - có vẻ như là một lỗi đối với tôi nhưng điều này đã không bắt đầu gây ra lỗi cho đến gần đây trên các công cụ tôi cung cấp cho các máy chủ này đã tồn tại trong nhiều năm - Tôi tin rằng Microsoft đã bắt đầu tung ra các thay đổi hệ thống đã cập nhật điều này hành vi buộc kết nối TLS trừ khi không có giải pháp thay thế nào khác.

Dù sao - nếu bạn vẫn gặp phải vấn đề này với một số trang web / máy chủ cũ, bạn nên thử.


1
Chúng tôi có một mô-đun CUCMPowerShell để sử dụng api Cisco Unified Communications AXL qua PowerShell và câu trả lời của bạn đã giúp chúng tôi khắc phục vấn đề này bằng cách thêm [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3. Cảm ơn bạn! Mã đầy đủ có thể được nhìn thấy trong Hàm Invoke-CUCMSOAPAPIF
Chris Magnuson

2
@Jeff - Kiểm tra bài viết được liên kết. Tôi nghĩ rằng nó có thể giải thích tại sao Ssl3 không hoạt động và đề xuất hai cách để kích hoạt lại Ssl3. docs.microsoft.com/en-us/dotnet/framework/migration-guide/…
Scott

4

di chuyển dòng này: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Trước dòng này: HttpWebRequest request = (HttpWebRequest) WebRequest.Create (uri);

Bài gốc: Bản cập nhật bảo mật KB4344167 phá vỡ Mã TLS


1
Sau khi thử tất cả các cách trên đều không có kết quả, đây là câu trả lời: ServicePointManager cần được đặt trước khi tạo HttpWebRequest.
Henry Rusted

1

Trong trường hợp của tôi, TLS1_2 được bật cả trên máy khách và máy chủ nhưng máy chủ đang sử dụng MD5 trong khi máy khách tắt nó. Vì vậy, hãy kiểm tra cả máy khách và máy chủ trên http://ssllabs.com hoặc kiểm tra bằng openssl / s_client để xem điều gì đang xảy ra. Ngoài ra, hãy kiểm tra mật mã đã chọn bằng Wireshark.


1

TLS 1.0 và 1.1 hiện là End of Life. Một gói trên máy chủ web Amazon của chúng tôi đã cập nhật và chúng tôi bắt đầu gặp lỗi này.

Câu trả lời là ở trên, nhưng bạn không nên sử dụng tlshoặc tls11nữa.

Đặc biệt đối với ASP.Net, hãy thêm nó vào một trong các phương pháp khởi động của bạn.

        public Startup()
        {
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;

nhưng tôi chắc chắn rằng một cái gì đó như thế này sẽ hoạt động trong nhiều trường hợp khác.


0

Nếu bạn đang sử dụng một tên miền mới và bạn đã thực hiện tất cả các bước trên mà vẫn gặp lỗi tương tự, hãy kiểm tra xem bạn đã xóa bộ nhớ cache DNS trên PC của mình chưa. Xóa DNS của bạn để biết thêm chi tiết.

Windows® 8

Để xóa bộ nhớ cache DNS của bạn nếu bạn sử dụng Windows 8, hãy thực hiện các bước sau:

Trên bàn phím, nhấn Win + X để mở Menu WinX.

Nhấp chuột phải vào Command Prompt và chọn Run as Administrator.

Chạy lệnh sau:

ipconfig / flushdns

Nếu lệnh thành công, hệ thống trả về thông báo sau:

Cấu hình IP Windows đã xóa thành công Bộ đệm phân giải DNS.

Windows® 7

Để xóa bộ nhớ cache DNS của bạn nếu bạn sử dụng Windows 7, hãy thực hiện các bước sau:

Nhấp vào Bắt đầu.

Nhập cmd vào hộp văn bản tìm kiếm trên menu Bắt đầu.

Nhấp chuột phải vào Command Prompt và chọn Run as Administrator.

Chạy lệnh sau:

ipconfig / flushdns

Nếu lệnh thành công, hệ thống sẽ trả về thông báo sau: Cấu hình Windows IP đã xóa thành công Bộ đệm phân giải DNS.


ipconfig /flushdnstrong C #?
Kiquenet

0

Tôi xem qua chủ đề này vì tôi cũng gặp lỗi Không thể tạo kênh bảo mật SSL / TLS. Trong trường hợp của tôi, tôi đang cố gắng truy cập API REST cấu hình Siebel từ PowerShell bằng cách sử dụng Invoke-RestMethodvà không có đề xuất nào ở trên hữu ích.

Cuối cùng, tôi tình cờ phát hiện ra nguyên nhân gây ra sự cố của mình: máy chủ mà tôi đang liên hệ yêu cầu xác thực chứng chỉ ứng dụng khách.

Để thực hiện các cuộc gọi hoạt động, tôi phải cung cấp chứng chỉ ứng dụng khách (bao gồm cả khóa cá nhân) với -Certificatetham số:

$Pwd = 'certificatepassword'
$Pfx = New-Object -TypeName 'System.Security.Cryptography.X509Certificates.X509Certificate2'
$Pfx.Import('clientcert.p12', $Pwd, 'Exportable,PersistKeySet')
Invoke-RestMethod -Uri 'https://your.rest.host/api/' -Certificate $Pfx -OtherParam ...

Hy vọng rằng kinh nghiệm của tôi có thể giúp ích cho người khác, những người có quan điểm cụ thể của tôi về vấn đề này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.