2012-02-29 97 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。