C# https双向认证,"请求被中止: 未能创建 SSL/TLS 安全通道"解决办法

最近的项目中用到了调用https的接口的功能,编写出程序后在我自己的电脑上运行没有问题,但是在同事的电脑上和服务上都没有办法正常运行,提示“请求被中止: 未能创建 SSL/TLS 安全通道”,最后在项目经理的帮助下和网上查找了大量的资料,以及做了大量的测试下终于解决了问题,所以想和大家分享下,避免大家像我一样耗费太多时间在这个问题上。

首先感谢广大网友的分享的解决方法和项目经理的帮助,否则我可能还是找不到问题的解决方法。

这是我写的代码:

using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace ssl
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var keystorefile = @"D:\xxx\xxxx.p12";
                var keypasswd = "xxxxxx";
                var url = "https://xxxxxxxxxx";
                var data = Encoding.UTF8.GetBytes("xxxx");
                var request = (HttpWebRequest)WebRequest.Create(url);
                //X509Certificate2 支持读取.p12格式的证书
                var cer = new X509Certificate2(keystorefile, keypasswd);
                request.ClientCertificates.Add(cer);
                ServicePointManager.ServerCertificateValidationCallback += (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)=>
                {
                    return true;
                };
                //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();
                var context = new StreamReader(response.GetResponseStream(),Encoding.UTF8).ReadToEnd();
                Console.WriteLine(context);
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message);
            }
            Console.Read();

        }
    }
}

在有的电脑会上运行会出现"请求被中止: 未能创建 SSL/TLS 安全通道"的问题,原因似乎是由于直接从磁盘读取证书导致的,但是具体原因不清楚,解决方法就是将证书导入系统,然后再调用系统证书存储空间中的证书。方法如下:

    //查找我们导入的证书
    X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    certStore.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindBySubjectName, "安装的证书名字", false);

另一个原因是用户权限不够,可以使用winhttpcertcfg.exe工具,进入cmd 执行如下命令:

winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "安装的证书名字" -a "Eeveryone"

最后的代码是这样:

using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace ssl
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var url = "https://xxxxxxxxxx";
                var data = Encoding.UTF8.GetBytes("xxxx");
                var request = (HttpWebRequest)WebRequest.Create(url);
                //X509Certificate2 支持读取.p12格式的证书
                   //查找我们导入的证书
                X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                certStore.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindBySubjectName, "安装的证书名字", false);
                request.ClientCertificates.Add(certCollection[0]));
                ServicePointManager.ServerCertificateValidationCallback += (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)=>
                {
                    return true;
                };
                //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                var response = (HttpWebResponse)request.GetResponse();
                var context = new StreamReader(response.GetResponseStream(),Encoding.UTF8).ReadToEnd();
                Console.WriteLine(context);
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message);
            }
            Console.Read();

        }
    }
}

参考资料:

https://www.cnblogs.com/jesselzj/p/6007118.html

https://www.cnblogs.com/ccsharp/p/3270344.html

你可能感兴趣的:(C# https双向认证,"请求被中止: 未能创建 SSL/TLS 安全通道"解决办法)