2009-08-19 38 views
27

Sử dụng Visual Studio 2005 - C# 2.0, System.Net.WebClient.UploadData(Uri address, byte[] data) Windows Server 2003Làm thế nào để bỏ qua một lỗi chứng chỉ với C# 2.0 WebClient - mà không có giấy chứng nhận

Vì vậy, đây là một phiên bản rút gọn mã:

static string SO_method(String fullRequestString) 
{ 
    string theUriStringToUse = @"https://10.10.10.10:443"; // populated with real endpoint IP:port 
    string proxyAddressAndPort = @"http://10.10.10.10:80/"; // populated with a real proxy IP:port 
    Byte[] utf8EncodedResponse; // for the return data in utf8 
    string responseString; // for the return data in utf16 

    WebClient myWebClient = new WebClient(); // instantiate a web client 
    WebProxy proxyObject = new WebProxy(proxyAddressAndPort, true);// instantiate & popuylate a web proxy 
    myWebClient.Proxy = proxyObject; // add the proxy to the client 
    myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); // stick some stuff in the header 

    UTF8Encoding utf8Encoding = new UTF8Encoding(false);// create a utf8 encoding 
    Byte[] utf8EncodedRequest = HttpUtility.UrlEncodeToBytes(fullRequestString, utf8Encoding); // convert the request data to a utf8 byte array 

    try 
    { 
     utf8EncodedResponse = myWebClient.UploadData(theUriStringToUse, "POST", utf8EncodedRequest); // pass the utf8-encoded byte array 
     responseString = utf8Encoding.GetString(utf8EncodedResponse); // get a useable string out of the response 
    } 
    catch (Exception e) 
    { 
     // some other error handling 
     responseString = "<CommError><![CDATA[" + e.ToString() + "]]></CommError>";// show the basics of the problem 
    } 
    return responseString;// return whatever ya got 
} 

Đây là lỗi tôi nhận được:

Kết nối cơ bản đã bị đóng: Không thể thiết lập mối quan hệ tin cậy cho kênh bảo mật SSL/TLS.

Tôi không có nhiều quyền kiểm soát để xem điều gì đang xảy ra khi yêu cầu xuất hiện. Tôi được thông báo rằng nó đến đích chính xác và có "lỗi chứng chỉ". Điều này được cho là bởi vì có sự không phù hợp theo nghĩa đen giữa địa chỉ IP trong yêu cầu của tôi và URL mà nó giải quyết. Tôi có nhiều hơn một IP mà tôi cho là phải làm tròn để chỉ định URL sẽ không hoạt động. Tôi không đính kèm chứng chỉ - cũng không phải tôi phải theo các chủ sở hữu điểm cuối. Mỗi "chúng" lỗi chứng chỉ là 'bình thường và tôi phải bỏ qua nó.

Chứng chỉ được đề cập được cho là một trong nhiều chứng chỉ verisign "chỉ có" trên máy chủ của chúng tôi. Các ví dụ tôi đã thấy để bỏ qua các lỗi cert dường như ngụ ý rằng người yêu cầu đang đính kèm một chứng chỉ x509 cụ thể (mà tôi không có).

Tôi đã xem qua .net WebService, bypass ssl validation! mà kinda-sorta mô tả vấn đề của tôi - ngoại trừ nó cũng kinda-sorta không phải vì tôi không biết chứng chỉ nào (nếu có) tôi nên tham khảo.

Có cách nào để tôi bỏ qua lỗi mà không thực sự biết/quan tâm chứng chỉ nào gây ra sự cố không?

  • và vui lòng - găng tay trẻ em, từ nhỏ và mã "cho núm vú" vì tôi không chính xác là người đam mê nặng.

  • Lưu lượng truy cập này nằm trên một đường riêng - vì vậy sự hiểu biết của tôi là bỏ qua lỗi cert không phải là một thỏa thuận lớn như thể đó là lưu lượng truy cập internet mở.

Trả lời

48

Chứng chỉ SSL dành cho máy để thiết lập mối quan hệ tin cậy. Nếu bạn gõ vào một địa chỉ IP, và kết thúc nói chuyện với một địa chỉ khác, âm thanh giống như lỗi bảo mật DNS hijack, loại SSL đang có ý định giúp bạn tránh - và có lẽ bạn không muốn đưa lên từ họ".

Nếu bạn có thể kết thúc nói chuyện với nhiều hơn máy (lý tưởng họ sẽ làm cho nó xuất hiện như một cho bạn), bạn sẽ cần một giấy chứng nhận cho mỗi máy có thể để bắt đầu tin tưởng.

Để bỏ qua niềm tin (Tôi đã chỉ từng có để làm điều này tạm thời trong các kịch bản phát triển) đoạn sau đây có thể làm việc cho bạn, nhưng tôi khuyên bạn xem xét các tác động của phớt lờ tin tưởng trước khi sử dụng nó:

public static void InitiateSSLTrust() 
{ 
    try 
    { 
     //Change SSL checks so that all checks pass 
     ServicePointManager.ServerCertificateValidationCallback = 
      new RemoteCertificateValidationCallback(
       delegate 
       { return true; } 
      ); 
    } 
    catch (Exception ex) 
    { 
     ActivityLog.InsertSyncActivity(ex); 
    } 
} 
+0

Cảm ơn, MattH. Tôi đang thực thi mã bạn có trong khối lệnh TRY trước khi gọi phương thức System.Net.WebClient.UploadData (địa chỉ Uri, byte []). Để nói rằng tôi không chắc những gì nó đang làm sẽ là một cách nói. Tôi không thấy liên kết với WebClient của tôi. Tuy nhiên, nó "xuất hiện" để được làm việc như chúng tôi dường như nhận được thêm trong giao tiếp của chúng tôi cho mỗi nhóm mạng bên cạnh tôi. Tôi tìm thấy một gợi ý rất giống nhau về MSDN nhưng những từ chỉ muốn tung ra khỏi nhãn cầu của tôi. http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager%28VS.80%29.aspx –

+1

Tóm lại, mã trên tin tưởng bất kỳ ai và bỏ qua tất cả xác minh SSL và do đó không an toàn . – MattH

+0

Quyền - đó là nhiều tôi đã nhận - nhưng là điều này gắn liền với trường hợp cụ thể của tôi về một WebClient, quá trình chạy của tôi, hoặc BẤT CỨ cert liên quan "goings trên" trên máy chủ một khi điều này thực hiện? Dự đoán của tôi là nó được giới hạn trong quá trình của tôi nhưng ... –

7

Mã này rộng hơn nhiều so với bạn có thể mong đợi. Đó là toàn bộ quá trình. Quá trình này có thể là exe, IIS trên máy này, hoặc thậm chí DLLHost.exe. Sau khi gọi nó, có một khối cuối cùng mà khôi phục lại mọi thứ bình thường bằng cách loại bỏ các đại biểu luôn luôn trả về sự thật.

+0

Đây là một gợi ý tốt, đăng nó? –

7

Đây là phần mã chúng tôi đang sử dụng (chưa được đánh bóng - Tôi không nghĩ mình có thiết lập xử lý lỗi chính xác nhưng phải đóng) dựa trên đề xuất của thomas (đây là mã .NET 4.0, mặc dù):

var sslFailureCallback = new RemoteCertificateValidationCallback(delegate { return true; }); 

try 
{ 

    if (ignoreSslErrors) 
    { 
     ServicePointManager.ServerCertificateValidationCallback += sslFailureCallback; 
    } 

    response = webClient.UploadData(Options.Address, "POST", Encoding.ASCII.GetBytes(Options.PostData)); 

} 
catch (Exception err) 
{ 
    PageSource = "POST Failed:\r\n\r\n" + err; 
    return PageSource; 
} 
finally 
{ 
    if (ignoreSslErrors) 
    { 
     ServicePointManager.ServerCertificateValidationCallback -= sslFailureCallback; 
    } 
} 
9

Tôi nhận thấy đây là một bài đăng cũ, nhưng tôi chỉ muốn thể hiện rằng có cách làm ngắn hơn (với .NET 3.5 trở lên).

Có lẽ đó chỉ là OCD của tôi, nhưng tôi muốn giảm thiểu mã này càng nhiều càng tốt. Đây dường như là con đường ngắn nhất để làm điều đó, nhưng tôi cũng đã liệt kê một số các khoản tương đương còn dưới đây:

// 79 Characters (72 without spaces) 
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true; 

cách ngắn nhất trong .NET 2.0 (đó là những gì các câu hỏi đã được đặc biệt yêu cầu về)

// 84 Characters 
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

Thật không may là cách lambda yêu cầu bạn xác định các tham số, nếu không nó có thể ngắn hơn.

Và trong trường hợp bạn cần một cách lâu hơn nữa, đây là một số lựa chọn thay thế bổ sung:

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

ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; }; 

// 255 characters - lots of code! 
ServicePointManager.ServerCertificateValidationCallback = 
    new RemoteCertificateValidationCallback(
     delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 
     { 
      return true; 
     }); 
+0

Mặc dù điều này có thể có trường hợp sử dụng nếu bạn muốn tắt xác thực chứng chỉ trong lớp chính của mình, bạn nên nhớ rằng điều này có thể dẫn đến rò rỉ bộ nhớ tiềm ẩn, nếu được sử dụng bên trong lớp được xây dựng theo yêu cầu. Ngoài ra '+ =' sẽ được sử dụng để đăng ký cuộc gọi lại này. –

1

Tôi muốn tắt xác minh SSL cho một lĩnh vực cụ thể mà không toàn cầu khử hoạt nó vì có thể có những yêu cầu khác chạy mà nên không bị ảnh hưởng, vì vậy tôi đã đưa ra giải pháp này (xin lưu ý rằng uri là một biến bên trong một lớp:.

 private byte[] UploadValues(string method, NameValueCollection data) 
     { 
      var client = new WebClient(); 

      try 
      { 
       ServicePointManager.ServerCertificateValidationCallback += 
        ServerCertificateValidation; 

       returnrclient.UploadValues(uri, method, parameters); 

      } 
      finally 
      { 
       ServicePointManager.ServerCertificateValidationCallback -= 
        ServerCertificateValidation; 
      } 
     } 

     private bool ServerCertificateValidation(object sender, 
      X509Certificate certificate, X509Chain chain, 
      SslPolicyErrors sslPolicyErrors) 
     { 
      var request = sender as HttpWebRequest; 
      if (request != null && request.Address.Host.Equals(
       this.uri.Host, StringComparison.OrdinalIgnoreCase)) 
       return true; 
      return false; 
     } 
1

đây là mã VB.net để làm cho WebClient bỏ qua cert SSL

Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True) 
Các vấn đề liên quan