无法创建SSL / TLS安全通道 - HttpWebRequest

时间:2018-01-08 21:34:07

标签: c# ssl https kubernetes httpwebrequest

我正在尝试建立与我的kubernetes api的连接,似乎无法从C#中使用SSL。

当我通过curl运行以下内容时,一切似乎都按预期工作:

enter image description here

我有这个让c#做同样的事情:

try
{
    // use the TLS protocol 
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

    // create HTTP web request with proper content type
    HttpWebRequest request = WebRequest.Create(Constants.K8_API_RC_URI) as HttpWebRequest;
    request.ContentType = "application/json;charset=UTF8";
    request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + Constants.K8_TOKEN);
    // load the X.509 certificate and add to the web request
    X509Certificate cert = new X509Certificate(Constants.K8_CRT);
    request.ClientCertificates.Add(cert);

    // call the web service and get response
    WebResponse response = request.GetResponse();

    Stream responseStream = response.GetResponseStream();

    string jsonContents = new StreamReader(responseStream).ReadToEnd();
}
catch (Exception exc)
{
    // log and print out error
    log.Info(exc.Message);
}

哪里

  

Constants.K8_CRT是ca.crt的路径

和ca.crt包含以下内容:

-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgIIcwd9rrnaPcowDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIYWNzazhz
and more letters.......
cwSfuIp7e49KC3HSqcU3Mz4oFNm5bw==
-----END CERTIFICATE-----

我收到以下错误:

  

无法创建SSL / TLS安全通道。

P.S。我知道有.Net的Kubernetes客户端,我已经尝试了所有这些客户端,但由于我将其与Azure Functions集成,因此大多数第三方库因各种原因无法运行。

2 个答案:

答案 0 :(得分:1)

CA证书应该用于验证服务器证书链,而不是作为ClientCertificate传递。

这是一个例子。

ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => {
    if (errors == SslPolicyErrors.None) return true;
    X509Certificate2 serverCert = new X509Certificate2(certificate);
    X509Certificate2 caCert = new X509Certificate2(@"./ca.cert");
    chain.ChainPolicy.ExtraStore.Add(caCert);
    chain.Build(serverCert);
    foreach (var chainStatus in chain.ChainStatus) {
        if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot) continue;
        if (chainStatus.Status != X509ChainStatusFlags.NoError) return false;
    }
    return true;
};

HttpWebRequest request = WebRequest.CreateHttp("https://master:6443/api/v1");
request.Headers[HttpRequestHeader.Authorization] = "Bearer " + "SOME_TOKEN";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var content = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.WriteLine(content);

答案 1 :(得分:0)

感谢@ Jimi的评论我能够通过添加以下内容来实现这一点:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
            delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                    System.Security.Cryptography.X509Certificates.X509Chain chain,
                                    System.Net.Security.SslPolicyErrors sslPolicyErrors)
                {
                    return true; // **** Always accept
                };

注意:我确定这只会忽略SSL验证,并在没有它的情况下继续。在我们的例子中,这是可以接受的。