完全解决:请求被停止: 未能建立 SSL/TLS 安全通道

最近有个项目要调用客户用java写的带https的webservice,对方提供了证书文件 test.pfx,我这里调用方式以下:java

//webservice代理类
SvcService svc = new SvcService();
//证书文件路径
string filePath = ConfigurationManager.AppSettings["pfxUrl"];
X509Certificate cert = new System.Security.Cryptography.X509Certificates.X509Certificate(filePath, "123456");

//将证书添加客户端证书集合
svc.ClientCertificates.Add(cert);

//webservice调用代码...

测试调用报错:请求被停止: 未能建立 SSL/TLS 安全通道,因而赶忙google,找到以下解决方案:web

在webservice代理类的构造函数中添加下面的代码,绕过服务器证书验证。安全

public static bool CheckValidationResult(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
        return true;
}
        
public SvcService() 
{
    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            
    this.Url = ConfigurationManager.AppSettings["host"];
}

本地vs环境下再试,好了!调用成功!不报错了!因而赶忙发布到IIS服务器上试一下,郁闷的是服务器上竟然报错,仍是这个未能建立 SSL/TLS 安全通道!服务器

因而继续google,找到下面的解决方法:函数

1.将客户端证书文件导入到本地计算机帐户下的我的存储区工具

2.下载winhttpcertcfg.exe 这个工具,下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=19801测试

3.安装后通常是在C:\Program Files\Windows Resource Kits\Tools这个路径下面。 进入cmd 执行以下命令:winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "test" -a "NetworkService"网站

这里解释一下这几个参数的含义:this

-g 是grant受权的意思,将该证书的使用权限授予某个用户google

-c 是certstore证书存储区,指定 本地计算机/当前用户下的证书存储区位置,咱们这里是MY,我的存储区

-s 是subjectstr 用于模糊匹配证书的一个字符串,咱们这里用证书文件名 test

-a 是account要受权的用户账号

这里要注意的是受权帐户,IIS6下面通常用的是NetworkService,若是你用的IIS7,必需要保证你网站所用的应用程序池的 "标识"和要受权的帐户一致

执行成功以后,会列出模糊匹配出的证书列表和已经受权的帐户。

而后程序代码作以下更改:

//webservice客户端代理类
SvcService svc = new SvcService();
//打开本地计算机下的我的证书存储区
X509Store certStore = new System.Security.Cryptography.X509Certificates.X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);
//根据名称查找匹配的证书集合,这里注意最后一个参数,传true的话会找不到
X509Certificate2Collection certCollection = certStore.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "test", false);
//将证书添加至客户端证书集合
svc.ClientCertificates.Add(certCollection[0]);

//webservice调用代码

再测试了一下,调用正常!至此这个问题算圆满解决了!总结:咱们导入的客户端证书并非全部的帐户都能访问和使用,由于咱们的开发服务器也就是VS自带的服务器默认使用当前用户,而当前用户具备使用证书的权限,因此咱们在本地调试的时候,一切正常。当咱们将网站部署到IIS后,因为IIS的使用的是内置帐户不具备证书的使用权限,因此就出现了上述问题,这个时候咱们只需用winhttpcertcfg这个工具给指定帐户授予使用证书的权限,就能够正常调用啦!

相关文章
相关标签/搜索