请求已中止:无法创建SSL/TLS安全信道

12

可能重复:
请求中止:无法创建 SSL/TLS 安全通道

我正在尝试使用客户端证书发送 HTTP 请求,该文件是一个 .p12 文件。但是当它到达 responseStream = httpRequest.GetRequestStream(); 这一行时,它会抛出一个 WebException:System.Net.WebException: 请求中止:无法创建 SSL/TLS 安全通道。

我正在 IIS7.5 上进行调试(在 Windows 7 上),应用程序池标识为“LocalSystem”。

如何解决这个问题?

        System.IO.Stream responseStream = null;
        string errorString = string.Empty;
        ;
        string postData = string.Empty;
        HttpWebRequest httpRequest = null;
        System.Text.Encoding Encoding = new System.Text.UTF8Encoding();
        try
        {
            XmlDocument orderXml = new XmlDocument();
            orderXml.Load(@"c:\xmlfile.xml");
            postData = orderXml.InnerXml;

            byte[] byte1 = Encoding.GetBytes(postData);

            httpRequest = (HttpWebRequest)WebRequest.Create("https://testurl.com/SOAP_v1_0/");
            httpRequest.Method = "POST";
            httpRequest.Timeout = 9000;
            httpRequest.KeepAlive = false;
            httpRequest.ContentType = "text/xml; charset=" + "utf-8";
            httpRequest.ContentLength = byte1.Length;

            X509Certificate2 certificate = new X509Certificate2(@"c:\file.p12", "password", X509KeyStorageFlags.Exportable);
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

            try
            {
                store.Open(OpenFlags.ReadWrite);

                if (!store.Certificates.Contains(certificate))
                {
                    store.Add(certificate);
                }

                int indexOfCertificate = store.Certificates.IndexOf(certificate);
                certificate = store.Certificates[indexOfCertificate];
            }

            finally
            {
                store.Close();
            }

            httpRequest.ClientCertificates.Add(certificate);

            responseStream = httpRequest.GetRequestStream();

            responseStream.Write(byte1, 0, byte1.Length);
        }
        catch (WebException webExcp)
        {
            errorString += "Error message: " + webExcp.Message;

            // Get the WebException status code.
            WebExceptionStatus status = webExcp.Status;

            if (status == WebExceptionStatus.ProtocolError)
            {
                // Get HttpWebResponse so that you can check the HTTP status code.
                HttpWebResponse httpResponse = (HttpWebResponse)webExcp.Response;
                errorString += "; The server returned protocol error " + httpResponse.StatusCode + " - " + httpResponse.StatusCode;
                httpResponse.Close();
            }
        }
        catch (Exception e)
        {
            errorString += "Error message: " + e.Message;
        }
        finally
        {
            if (responseStream != null)
            {
                responseStream.Close();
            }
        }
    }

使用跟踪日志时,以下是指定错误的行:

System.Net Information: 0 : [4968] SecureChannel#2399524 - Certificate is of type X509Certificate2 and contains the private key.

System.Net Information: 0 : [4968] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)

System.Net Error: 0 : [4968] AcquireCredentialsHandle() failed with error 0X8009030D.

System.Net Information: 0 : [4968] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)

System.Net Error: 0 : [4968] AcquireCredentialsHandle() failed with error 0X8009030D.
System.Net.Sockets Verbose: 0 : [4968] Socket#59311937::Dispose()

System.Net Error: 0 : [4968] Exception in the HttpWebRequest#50160154:: - The request was aborted: Could not create SSL/TLS secure channel.

System.Net Error: 0 : [4968] Exception in the HttpWebRequest#50160154::EndGetRequestStream - The request was aborted: Could not create SSL/TLS secure channel.

您能否使用浏览器成功导航到相同的URL?这是否成功建立了SSL / TLS会话? - Richard
我收到了“Internet Explorer无法显示网页”的错误信息。 - Rutger
因此,请通过错误页面上的链接查看详细信息。您需要知道为什么无法创建SSL/TLS通道。如果没有这些信息,我们只能猜测客户端和服务器的配置设置。 - Richard
我想我几个月前遇到了和你类似的问题,当时我在连接合作伙伴的系统时也遇到了困难。你在服务器端有获取到任何日志吗?他们应该能够为你提供一些信息,握手过程通常会失败。 - Luis Quijada
在我的情况下,将证书安装到Windows证书存储中解决了问题。 - thepirat000
1个回答

41

您需要为您的应用程序创建一个system.net日志。 您需要创建一个myapp.exe.config配置文件,并将以下内容放入其中。

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <system.diagnostics>
        <trace autoflush="true" />
        <sources>
            <source name="System.Net">
                <listeners>
                    <add name="System.Net" />
                </listeners>
            </source>
            <source name="System.Net.Sockets">
                <listeners>
                    <add name="System.Net" />
                </listeners>
            </source>
            <source name="System.Net.Cache">
                <listeners>
                    <add name="System.Net" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add
                name="System.Net"
                type="System.Diagnostics.TextWriterTraceListener"
                initializeData="System.Net.trace.log"
            />
        </sharedListeners>
        <switches>
            <add name="System.Net" value="Verbose" />
            <add name="System.Net.Sockets" value="Verbose" />
            <add name="System.Net.Cache" value="Verbose" />
        </switches>
    </system.diagnostics>
</configuration>

如果你使用这个配置文件运行,它将创建一个名为system.net.trace.log的日志文件。该文件将提供关于失败原因的更多细节。


更新了带有跟踪日志中的错误部分的问题。 - Rutger
如果您想要更详细的错误信息,请将 traceOutputOptions="DateTime, ProcessId, ThreadId, Callstack" 添加为 sharedListener System.Net 的属性。像这样: <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" traceOutputOptions="DateTime, ProcessId, ThreadId, Callstack" initializeData="System.Net.trace.log" /> - Ogglas
日志文件在哪里? - john k
@johnk 这将把日志文件(在这个例子中,命名为"System.Net.trace.log")放在应用程序所在的目录中。对于普通的Windows .exe应用程序来说,可能是你的应用程序.exe文件所在的文件夹。对于Web应用程序来说,可能是网站文件夹的根目录。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接