[C#]用HttpWebRequest加载证书建立SSL通道时发生异常的解决办法

简介:

编写者:郑昀@UltraPower

关键字:HttpWebRequest,

SSL,X509Certificate

dotNet  Framwork 1.1

编写时间:2005-3-29

WSE 2.0 SP3

 

目的:

对于用HttpWebRequest加载证书请求远端https服务器时,发生的

“基础连接已经关闭无法与远程服务器建立信任关系。”/

The underlying connection was closed. Could not establish a secure SSL/TLS connection”错误,我们可以用如下方式解决。

重现:

使用以下代码,你就可以得到这个错误“基础连接已经关闭无法与远程服务器建立信任关系”:

using System;

using System.Text;

using System.Net;

using System.IO;

using System.Security.Cryptography.X509Certificates;

 

using Microsoft.Web.Services2.Security;

using Microsoft.Web.Services2.Security.Tokens;

using Microsoft.Web.Services2.Security.X509;

 

static void Main(string[] args)

        {

            StringBuilder sb=new StringBuilder();

            string _strToRequest = "send";

 

            try

            {

                //POST请求开始

                byte[] bt=Encoding.Default.GetBytes("send");

                HttpWebRequest Req=(HttpWebRequest)System.Net.WebRequest.Create("https://202.108.CCC.XXX:Port//");

                Req.KeepAlive=true;

                //Req.Timeout=60000;

                Req.ContentType="text/xml";

                Req.ContentLength=_strToRequest.Length;

                Req.Method="POST";

                X509CertificateStore store = X509CertificateStore.CurrentUserStore( X509CertificateStore.MyStore );

                store.OpenRead();

    

                //读取证书的keyid

                Microsoft.Web.Services2.Security.X509.X509CertificateCollection certs =

                    store.FindCertificateByKeyIdentifier( Convert.FromBase64String( "CXv+xZ78zI3qWHGJ6Wh9BF6B23A=" ) );

                X509SecurityToken token = null;

                if (certs.Count > 0)

                {

                    // 得到证书存储区的第1个人证书

                    token = new X509SecurityToken( ((Microsoft.Web.Services2.Security.X509.X509Certificate) certs[0]) );

                } 

                if(token != null)

                    Req.ClientCertificates.Add(token.Certificate);

                Req.KeepAlive=true;

 

                Stream ReqStream=Req.GetRequestStream();

                ReqStream.Write(bt,0,bt.Length);

                ReqStream.Close();

                //得到响应

                HttpWebResponse res=(HttpWebResponse)Req.GetResponse();

                StreamReader sr=newStreamReader(res.GetResponseStream(),Encoding.Default);

                sb.Append(sr.ReadToEnd());

                res.Close();

                sr.Close();

            }

            catch(Exception ex)

            {    

                sb.Remove(0,sb.Length);

                sb.Append("<?xml version=\"1.0\" encoding=\"gb2312\"?>\n");

                sb.Append("<slia ver=\"1.0.0\">\n");

                sb.Append("<result resid=\"501\">"+ex.Message+"</result>\n");

                sb.Append("</slia>\n");

            }

 

            Console.WriteLine(sb.ToString());

 

            Console.Read();

        }

原因:

在“http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpguide/html/cpconhostingremoteobjectsininternetinformationservicesiis.asp”提到:

证书标识特定的计算机,该计算机的名称位于证书的公共名称中。但是,很容易就会更改计算机的名称或使用客户端配置文件中的“localhost”,这会在客户端和服务器证书中的公共名称之间造成不匹配的情况。在 .NET Framework 1.0 版中,这一不匹配的情况将被忽略,并且将在服务器上引发调用。

 .NET Framework 1.1 版开始,这一不匹配的情况会引发以下异常:“System.Net.WebException:基础连接已经关闭:无法与远程服务器建立信任关系”。如果您无法配置远程处理客户端以使用证书公共名称,则可以使用客户端应用程序配置文件中的以下设置重写这一不匹配的情况。

<system.net>

   <settings>

      <servicePointManager

         checkCertificateName="true"

      />

   </settings>

</system.net>

若要以编程方式使客户端忽略证书名称不匹配,客户端必须创建一个特定类的实例,如果 certificateProblem值为 0x800c010f,该类将实现 ICertificatePolicy 接口并实现 CheckValidationResult 方法以返回true。然后,您必须将该对象注册到 System.Net.ServicePointManager 对象,方法是将该对象传递到ServicePointManager.CertificatePolicy 属性。”

解决之道:

但是用它列出的代码还是不对,我们改为CheckValidationResult无条件返回true即可。如下所示声明一个TrustAllCertificatePolicy类:

 

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy

        {

            public TrustAllCertificatePolicy()

            {}

 

            public bool CheckValidationResult(ServicePoint sp,

                System.Security.Cryptography.X509Certificates.X509Certificate cert,

                WebRequest req, int problem)

            {

                return true;

            }

        }

然后,在请求之前加上

System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

即可。

这样,代码就可以顺利和https服务器建立SSL通道了。

编写者:郑昀@UltraPower

目录
相关文章
|
9月前
|
安全 数据建模 应用服务中间件
阿里云SSL证书价格、证书类型及免费版证书申请和证书部署教程参考
阿里云SSL证书有收费版也有免费版,收费版DV域名级SSL类型405元起,免费版证书为DV域名级SSL类型,每个实名个人和企业主体在一个自然年内可以一次性领取20张免费证书。本文为大家详细介绍阿里云SSL证书价格情况,包括不同域名类型、证书类型、证书等级和证书品牌的相关收费标准,以及免费版证书的申请和部署教程参考。
|
5月前
|
网络协议 应用服务中间件 网络安全
阿里云SSL证书申请具体操作流程,以申请免费SSL证书为例
阿里云免费SSL证书由Digicert提供,单域名可申请20张,有效期3个月。通过数字证书管理控制台,完成购买、域名验证(DNS或文件)、提交审核后下载,支持Nginx、Apache等多服务器格式。
627 0
|
7月前
|
存储 机器学习/深度学习 监控
公司监控软件有哪些?监测方案:基于布隆过滤器的 C# 异常行为检测实践探索
本文探讨了布隆过滤器在公司监控软件中的技术应用,介绍其原理、优势及C#实现代码,助力企业高效构建数据安全防护体系。
202 0
|
9月前
|
安全 网络安全 流计算
修改代码以确保对SSL和HTTP异常的正确处理。
记得,在海上和代码世界里,风暴总是突如其来。但只要你的代码准备妥当,合理地处理SSL和HTTP异常,你的小船就能安全航行,最终到达它的目的地。
198 12
|
10月前
|
存储 SQL 数据库连接
C#程序调用Sql Server存储过程异常处理:调用存储过程后不返回、不抛异常的解决方案
本文分析了C#程序操作Sql Server数据库时偶发的不返回、不抛异常问题,并提出了解决思路。首先解析了一个执行存储过程的函数`ExecuteProcedure`,其功能是调用存储过程并返回影响行数。针对代码执行被阻塞但无异常的情况,文章总结了可能原因,如死锁、无限循环或网络问题等。随后提供了多种解决方案:1) 增加日志定位问题;2) 使用异步操作提升响应性;3) 设置超时机制避免阻塞;4) 利用线程池分离主线程;5) 通过信号量同步线程;6) 监控数据库连接状态确保可用性。这些方法可有效应对数据库操作中的潜在问题,保障程序稳定性。
754 11
|
12月前
|
运维 安全 数据建模
阿里云数字证书管理服务免费版和收费版SSL证书区别、收费标准、申请及部署教程参考
阿里云数字证书管理服务提供多种SSL证书类型和品牌,适用于不同规模的网站,包括但不限于电商、小型企业、大型企业或个人等。阿里云SSL证书有收费版的也有免费版的,有的新手用户由于是初次在阿里云申请SSL证书,可能不是很清楚免费版证书的申请和部署流程,本文为以图文形式为大家展示阿里云免费版SSL证书最新的申请及部署教程,以供参考。
|
12月前
|
算法 数据建模 应用服务中间件
阿里云2025智惠采购季,WoSign SSL证书优惠叠加使用攻略
阿里云2025智惠采购季,WoSign SSL证书折上折满减优惠!活动月期间(2025年03月01日至03月31日)活动折扣叠加满减优惠券,具体如何操作才能获取组合优惠价格呢?快来get优惠券组合使用攻略吧!
826 4
|
12月前
|
数据建模 网络安全
阿里云申请SSL证书价格多少钱一年?2025免费版和付费版收费标准
阿里云SSL证书提供免费和付费版本,适合不同需求。付费证书品牌涵盖WoSign、DigiCert、GlobalSign等,类型包括DV(域名验证)、OV(企业验证)和EV(扩展验证),价格从238元/年起,通配符和多域名证书价格更高。新用户享5折起优惠,全系列75折起。免费版由Digicert提供,仅支持单域名,有效期3个月,特殊域名可能无法申请。建议正式环境选用付费证书以确保稳定性与安全性。详情及申请流程可参考阿里云官方文档或控制台操作指引。
8662 0
|
6月前
|
XML 前端开发 C#
C#编程实践:解析HTML文档并执行元素匹配
通过上述步骤,可以在C#中有效地解析HTML文档并执行元素匹配。HtmlAgilityPack提供了一个强大而灵活的工具集,可以处理各种HTML解析任务。
321 19
|
7月前
|
监控 算法 C#
C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制
C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制
1340 0