asp.net在IIS环境中访问第三方需数字证书接口时 报 “请求被中止: 未能创建 SSL/TLS 安全通道”

最近做一个网站,需要访问第三方的接口(访问接口需要数字证数 *.pfx  文件),在VS环境下运行时完全正常,但放到IIS上就报"请求被中止: 未能创建 SSL/TLS 安全通道"、 “The request was aborted: Could not create SSL/TLS secure channel”。在网上找好久终于找到方法,在此与大家分享下,希望对遇到同样问题的 程序猿 有所帮助。


前题引如下以类库

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


最初完整源码如下:

    /// <summary>
    /// xxx
    /// </summary>
    /// <param name="xmlStr">xxx</param>
    /// <returns></returns>

   private string xmlSubject(string xmlStr)

    {

        string retXml = "";
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;   //SSL3协议替换成TLS协议
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
        HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create("https://xxxxxxx");
        
        X509Certificate cerCaiShang = new X509Certificate(“D:\Work\xxx.pfx”, "123456", X509KeyStorageFlags.MachineKeySet);
        httpRequest.ClientCertificates.Add(cerCaiShang);
        httpRequest.Method = "POST";
        httpRequest.ContentType = "application/x-www-form-urlencoded";
       
        byte[] payload = System.Text.Encoding.UTF8.GetBytes(xmlStr);                                    
        httpRequest.ContentLength = payload.Length;                                                 

        using (Stream writer = httpRequest.GetRequestStream())                                          
        {
            writer.Write(payload, 0, payload.Length);                                                 
            HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();               
            using (StreamReader srd = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default))
            {
                retXml = srd.ReadToEnd();              //读取文件流
                retXml = retXml.Replace("&lt;", "<");  //特殊字符处理
                retXml = retXml.Replace("&gt;", ">");  //特殊字符处理
            }
            response.Close();
        }
        return retXml;

   }


    /// <summary>
    /// 回调方法
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="certificate"></param>
    /// <param name="chain"></param>
    /// <param name="errors"></param>
    /// <returns></returns>
    public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
    {
        //为了通过证书验证,总是返回true
        return true;
    }


以上源码在VS环境 及 WinForm 程序中运行完全正常,但在IIS上就报  "请求被中止: 未能创建 SSL/TLS 安全通道",   经查找资料才知是 IIS 受权问题

解决办法及步骤如下:

1.将客户端证书文件导入到  本地计算机账户  下的个人存储区。

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

3.安装后 进入cmd 执行:

    a. cd C:\Program Files\Windows Resource Kits\Tools  

    b. winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "test" -a "NetworkService"


第1点中 导入证书方法如下:

将客户端的证书+私钥(pfx 或p12 文件),导入到操作系统(windows)的相关证书区域,步骤:
    Windows xp/2003
        1. 单击 开始 ,单击 运行 ,键入 mmc ,然后单击 确定 。
        2. 在 文件 菜单上单击 添加/删除管理单元 。
        3. 在 添加/删除管理单元 对话框中,单击 添加 。
        4. 在 添加独立管理单元 对话框单击 证书 ,然后单击 添加 。
        5. 在在 证书管理单元中 对话框中单击 计算机帐户 ,然后单击 下一步
        6. 在 选择计算机 对话框中,单击 完成 。
        7. 在 添加独立管理单元 对话框单击 关闭 ,然后单击 确定 。
        8. 展开 证书 (本地计算机) ,展开 个人 ,然后单击 证书 。
        9. 右键 -》 所有任务-》导入 选择你的证书导入
    Windows 7
        1. 单击 开始 ,单击 运行 ,键入 mmc ,然后单击 确定 。
        2. 在 文件 菜单上单击 添加/删除管理单元 。
        3. 在 可用的管理单元 列表中选择 证书 ,点击 添加 。
        4. 在 证书管理 对话框中选择 计算机账户 ,然后单击 下一步
        5. 在 选择计算机 对话框中,单击 完成 。
        6. 在 添加或删除管理单元 对话框单击 确定 。
        7. 展开 证书 (本地计算机) ,展开 个人 ,然后单击 证书 。
        8. 右键 -》 所有任务-》导入 选择你的证书导入


第3点中的参数含义:
-g 是grant授权的意思,将该证书的使用权限授予某个用户
-c 是certstore证书存储区,指定 本地计算机/当前用户下的证书存储区位置,我们这里是MY,个人存储区
-s 是subjectstr 用于模糊匹配证书的一个字符串,我们这里用证书文件名 test
-a 是account要授权的用户帐号

这里要注意的是授权账户,IIS6下面一般用的是NetworkService,如果你用的IIS7,必须要保证你网站所用的 应用程序池的 "标识"和要授权的账户一致。其它版本不用设置


执行成功之后,会列出模糊匹配出的证书列表和已经授权的账户.
然后程序代码做如下更改:

   private string xmlSubject(string xmlStr)

    {
        string retXml = "";
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
        HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create("https://xxxxxxx");

        X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        certStore.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindBySubjectName, "xxx", false);

        httpRequest.ClientCertificates.Add(certCollection[0]);
        httpRequest.Method = "POST";
        httpRequest.ContentType = "application/x-www-form-urlencoded";
      
        byte[] payload = System.Text.Encoding.UTF8.GetBytes(xmlStr);                              
        httpRequest.ContentLength = payload.Length;                                                
        using (Stream writer = httpRequest.GetRequestStream())                                           
        {
            writer.Write(payload, 0, payload.Length);                                                  
            HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();                
            using (StreamReader srd = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default))
            {
                retXml = srd.ReadToEnd();              //读取文件流
                retXml = retXml.Replace("&lt;", "<");  //特殊字符处理
                retXml = retXml.Replace("&gt;", ">");  //特殊字符处理
            }
            response.Close();
        }
        return retXml;

    }


更改后在VS 及 IIS中运行 OK ,问题圆满解决。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值