2012-02-29 93 views
5

我寫了一個C#程序,它使用HttpWebRequest連接到HTTPS站點。該GetResponse()方法拋出一個異常:如何將可信CA證書(不是客戶端證書)添加到HttpWebRequest?

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

我能夠連接到使用curl.exe --cacert CAFile.pem同一網站。我希望能夠使用C#程序中相同的可信CA證書。

如何獲得HttpWebRequest以使用此CA證書文件(或包含從其解析的證書的X509CertificateCollection)?

回答

6

嘗試設置你的ServerCertificateValidationCallback使用此:

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; 
} 

我還沒有機會來測試這一點,所以讓我知道如果您遇到任何錯誤,如果需要的話,我會修改答案。

+0

謝謝,明天再試吧 – ThiefMaster 2012-10-09 20:43:17

1

我最終實現的解決方案是寫與定製驗證邏輯實現ICertificatePolicy一類:

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; 
} 

(錯誤檢查不再贅述。)

_defaultPolicy可以設置爲ServicePointManager.CertificatePolicy以允許除了自定義證書之外,還將使用默認證書存儲區。

_certs包含額外的證書。它是通過解析PEM文件生成的,並致電_certs.Add(new X509Certificate(Convert.FromBase64String(base64cert)));

CertificatePolicy已被ServerCertificateValidationCallback廢棄,但我需要支持舊版本的.NET。