[C#]用HttpWebRequest加载证书建立SSL通道时发生异常的解决办法
对于用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
阿里云免费版SSL云盾证书申请流程 ssl证书可以快速实现域名由http升级为https,防止网站被拦截、被篡改、被劫持、被仿冒,阿里云提供免费版的SSL云盾证书,但是很多用户却找不到申请入口,下面就介绍下如何申请阿里云免费版SSL云盾证书。
关于 SSL 证书 在 HTTPS 协议大行其道的今天,其通信所需要的 SSL 证书也是不可或缺的一环,如果访问没有 SSL 证书的网站,就是下面这样的
郑昀 ☑移动数据业务 times;6年 ☑语义聚合 times;4年 ☑O2O times;5年的一个老兵。
相关文章
- C# ExecuteReader「建议收藏」
- c# mysql executenonquery_c#数据四种执行方法(ExecuteNonQuery)
- [030] C# 高级:TAP 异步编程
- C#常用正则表达式整理详解编程语言
- ssl证书Linux主机绑定SSL证书的方法(linuxhost绑定)
- Linux安装SSL证书:快速、简便、安全(linux安装ssl)
- Oracle安全加固之SSL配置(oracle配置ssl)
- Linux配置SSL证书:快速通过安全连接保护系统(linux配置ssl证书)
- 探索Linux世界:查看SSL版本(linux查看ssl版本)
- MySQL中SSL的配置和使用方法(mysql 中ssl)
- MySQL无法使用SSL加密连接(mysql 不支持ssl)
- Oracle SSL 运行安全准备就绪(oracle ssl开启)
- asp.net(c#)使用Rex正则来生成字符串数组的代码
- C#接口的隐式与显示实现及适应场景
- 深入c#绘制验证码的详解
- C#日期转换函数分享
- C#Hashtable/Dictionary写入和读取对比详解
- C#写日志类实例
- C#使用XML序列化操作菜单的方法
- C#中string和StingBuilder内存中的区别实例分析