<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>
用HttpWebRequest加载证书建立SSL通道时发生异常的解决办法
编写者:郑昀@UltraPower |
关键字:HttpWebRequest,
SSL,X509Certificate
|
dotNet Framwork 1.1 |
编写时间:<chsdate w:st="on" isrocdate="False" islunardate="False" day="29" month="3" year="2005"><span lang="EN-US">2005-3-29</span></chsdate> |
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 <place w:st="on">Main</place>(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+xZ78zI3qWHGJ6Wh9BF6B<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="36" unitname="a">23A</chmetcnv>=" ) );
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=new StreamReader(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='/"<chsdate' w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899">1.0.0/">/n");<p></p></slia>
sb.Append("<result resid='/"501/"'>"+ex.Message+"</result>/n");
sb.Append("/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><p></p></system.net>
<settings><p></p></settings>
<servicepointmanager></servicepointmanager>
checkCertificateName="true"
/>
若要以编程方式使客户端忽略证书名称不匹配,客户端必须创建一个特定类的实例,如果 certificateProblem 值为 0x<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="800" unitname="C">800c</chmetcnv><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="10" unitname="F">010f</chmetcnv>,该类将实现 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
分享到:
相关推荐
配置dotnet+nginx+SSL+centos
仅示例,button3有点问题 用于提问
dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-DotNETCore实现微信公众号被关注时推送消息dotnet-...
IIS 发布 Core Web 项目,发布后提示没有文件AspNetCoreModuleV2,这个时候需要在机器上安装dotnet-hosting、dotnet-sdk 以上两个文件时64位的。
dotNet Core 内存占用过高的解决方案dotNet Core 内存占用过高的解决方案
自动重新加载 ASP.NET core 开发
Vlc.DotNet-develop.zip 二次开发包SDK 请使用VS2017运行 Vlc.DotNet-develop.zip 二次开发包SDK 请使用VS2017运行 Vlc.DotNet-develop.zip 二次开发包SDK 请使用VS2017运行 Vlc.DotNet-develop.zip 二次开发包SDK ...
本软件是一个VS编译工具,是目前体积最小的VS编译器,支持c#、vb.net,支持winform和webform语言虽不能完全替代Visual studio,不过在没有Visual studio时,应急用下,还是不错的,此为dotNet1.1环境。 ------------...
DOTNET框架解决方案项目实训 包括报告 等 材料
有了这个,你可以在加载程序集追查面向对象编程(OOP)的结构,并找出如何组件被很容易地建立。 插件支持 以及许多其他。NET反编译器,旋转变压器的DotNet得到了一个插件系统,它允许你创建扩展应用程序。该系统...
Dotnet4.8高度兼容版,内含开发环境和运行环境脱机安装。
dotnet面试常见问题dotnet面试常见问题dotnet面试常见问题dotnet面试常见问题dotnet面试常见问题
Ascgen dotNET
centos7 安装dotnet完整操作步骤,并用supervisord服务启动dotnet程序
dotnet框架
相信很多人在安装Framework4.7时会出现因为证书问题导致安装失败的情况。本资源是dotNet Framework4.7.2离线安装包,包含安装包及cer证书。
多个较实用的dotnet dll引用文件,包括有重写的、编辑器、无刷新支持、依赖注入的
我的Unity框架,包含资源加载,配置加载,数据加载,UI管理,日志管理,动画系统,特效系统
dotnet core 2.1 中文&英文dotnet core 2.1 中文&英文dotnet core 2.1 中文&英文dotnet core 2.1 中文&英文dotnet core 2.1 中文&英文dotnet core 2.1 中文&英文dotnet core 2.1 中文&英文
dotnet 手册值得你拥有