2012-02-29 69 views
5

Tôi đã viết một chương trình C# sử dụng HttpWebRequest để kết nối với một trang web HTTPS. Phương pháp GetResponse() ném một ngoại lệ:Làm cách nào để thêm chứng chỉ CA đáng tin cậy (KHÔNG phải chứng chỉ ứng dụng khách) vào HttpWebRequest?

SystemError: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Tôi có thể kết nối với các trang web tương tự sử dụng curl.exe --cacert CAFile.pem. Tôi muốn có thể sử dụng cùng một chứng chỉ CA đáng tin cậy từ chương trình C#.

Tôi làm cách nào để có được HttpWebRequest để sử dụng tệp chứng chỉ CA này (hoặc X509CertificateCollection chứa chứng chỉ được phân tích cú pháp từ nó)?

Trả lời

6

Hãy thử thiết lập ServerCertificateValidationCallback bạn để sử dụng này:

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ 
    if (sslPolicyErrors == SslPolicyErrors.None) 
    return true; 

    X509Chain privateChain = new X509Chain(); 
    privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; 

    X509Certificate2 cert2 = new X509Certificate2(certificate); 
    X509Certificate2 signerCert2 = new X509Certificate2(@"C:\MyCACert.PEM"); 

    privateChain.ChainPolicy.ExtraStore.Add(signerCert2);  
    privateChain.Build(cert2); 

    bool isValid = true; 

    foreach (X509ChainStatus chainStatus in privateChain.ChainStatus) 
    { 
     if (chainStatus.Status != X509ChainStatusFlags.NoError) 
     { 
      isValid = false; 
      break; 
     } 
    } 

    return isValid; 
} 

tôi đã không có cơ hội để kiểm tra điều này, vì vậy hãy cho tôi biết nếu bạn gặp bất kỳ lỗi nào và tôi sẽ thay đổi câu trả lời, nếu cần thiết.

+0

Xin cảm ơn, hôm nay sẽ thử – ThiefMaster

1

Các giải pháp tôi cuối cùng thực hiện là để viết một lớp thực hiện ICertificatePolicy với xác nhận tùy chỉnh logic:

private X509CertificateCollection _certs; 
private ICertificatePolicy   _defaultPolicy; 

public bool CheckValidationResult(ServicePoint svcPoint, X509Certificate cert, WebRequest req, int problem) 
{ 
    if ((_defaultPolicy != null) && _defaultPolicy.CheckValidationResult(svcPoint, cert, req, problem)) 
    { 
     return true; 
    } 

    foreach (X509Certificate caCert in _certs) 
    { 
     if (caCert.Equals(cert)) 
     { 
      return true; 
     } 
    } 

    return false; 
} 

(Error-checking bỏ qua cho ngắn gọn.)

_defaultPolicy có thể được thiết lập để ServicePointManager.CertificatePolicy cho phép kho lưu trữ chứng chỉ mặc định được sử dụng ngoài chứng chỉ tùy chỉnh.

_certs chứa (các) chứng chỉ bổ sung. Nó được tạo bằng cách phân tích cú pháp tệp PEM và gọi số _certs.Add(new X509Certificate(Convert.FromBase64String(base64cert)));

CertificatePolicy đã bị lỗi thời bởi ServerCertificateValidationCallback, nhưng tôi cần hỗ trợ phiên bản cũ của .NET.

Các vấn đề liên quan