【问题标题】:Problem with HTTPs request and SslStream on some sites某些站点上的 HTTPs 请求和 SslStream 存在问题
【发布时间】:2021-02-27 01:48:54
【问题描述】:

我有一个简单的 C# 应用程序,它使用 TcpClientSslStream 发出 HTTPS 请求。一切正常,除了一些使用 TLS 1.3 的网站出现故障。我将项目升级到.Net Framework 4.8,也读得很慢https://docs.microsoft.com/es-es/dotnet/framework/network-programming/tls,但我无法解决。

我使用的是 Windows 10 64 位编译 19041.508。

我可以提供的最小代码示例如下:

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
        private void button1_Click(object sender, EventArgs e)
        {
            string hostname = "stackoverflow.com";

            using (TcpClient tcpClient = new TcpClient())
            {
                tcpClient.Connect(hostname, 443);

                //HTTP request headers
                string reqString = "GET / HTTP/1.1" + "\r\n";
                reqString += "Host: " + hostname + "\r\n";
                reqString += "Connection: Close\r\n\r\n";
                byte[] header_bytes = Encoding.ASCII.GetBytes(reqString);

                using (SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
                {
                    sslStream.AuthenticateAsClient(hostname, null, SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false);
                    sslStream.Write(header_bytes, 0, header_bytes.Length);

                    string response = "";
                    using (var memory = new MemoryStream())
                    {
                        sslStream.CopyTo(memory, 81920);
                        memory.Position = 0;
                        byte[] data = memory.ToArray();
                        response = Encoding.UTF8.GetString(data);
                        textBox1.Text = response;
                    }
                }
            }
        }

        //Validate certificates
        public static bool ValidateServerCertificate(
        object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;

            // Do not allow this client to communicate with unauthenticated servers.
            return false;
        }

如果您尝试使用主机名stackoverflow.com,它可以工作,但如果您使用例如manga1001.com,它会失败并引发异常。异常详情:

System.Security.Authentication.AuthenticationException
  HResult=0x80131501
  Mensaje = A call to SSPI failed, see inner exception.
  Origen = System
  Seguimiento de la pila:
   en System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   en System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   en System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   en http_minimal.Form1.button1_Click(Object sender, EventArgs e) en C:\Users\VA\source\repos\http_minimal\http_minimal\Form1.cs: línea 36
   en System.Windows.Forms.Control.OnClick(EventArgs e)
   en System.Windows.Forms.Button.OnClick(EventArgs e)
   en System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   en System.Windows.Forms.Control.WndProc(Message& m)
   en System.Windows.Forms.ButtonBase.WndProc(Message& m)
   en System.Windows.Forms.Button.WndProc(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   en System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   en System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   en System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   en System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   en System.Windows.Forms.Application.Run(Form mainForm)
   en http_minimal.Program.Main() en C:\Users\VA\source\repos\http_minimal\http_minimal\Program.cs: línea 19

Excepción interna 1:
Win32Exception: No se permite la función solicitada

希望有人能帮我解决这个问题,我花了很多时间但没有找到解决方案。

【问题讨论】:

  • 你能把整个异常贴在这里吗?
  • 添加了完整的异常文本。谢谢。
  • 这不是客户端问题,因为它适用于某些服务器而不适用于其他服务器。服务器是问题。确保服务器安装了相同的证书,并确保服务器具有相同版本的 Net。服务器正在使用什么应用程序?您是如何安装应用程序的?
  • 我不是服务器的所有者,服务器本身在互联网上运行,所以我不必在服务器上安装任何东西。我建议你慢慢阅读代码和描述的问题。所有经过测试的 webapges 都可以在 FireFox、Chrome 等中完美运行……只有在我尝试使用 SSLStream 代码访问时才会失败。

标签: c# ssl sslstream tls1.3


【解决方案1】:

经过令人沮丧的研究后,我将对此进行一些说明。似乎当前的 Windows 10 版本不完全支持 TLS 1.3。微软宣布更新TLS Cipher Suites in Windows 10 v21H1

换句话说,我们必须等到 Microsoft 发布该更新后才能检查问题是否仍然存在。目前无法解决问题,因为 Windows 10 v19042.685 (20H2) 无法支持所测试网页所需的 TLS 1.3 密码。

【讨论】:

    【解决方案2】:

    请尝试:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
    

    【讨论】:

    • 我应该在哪里使用它?我使用 SSLstream 测试并抛出相同的错误。您能否更详细地说明您的解决方案?
    • 我在启动时使用它,我使用 HttpWebRequest。尝试找到这样的代码: var request = (HttpWebRequest)WebRequest.Create(Address);
    • 如果你慢慢检查我的代码,我没有使用 HttpWebRequest,我使用的是 tcpclient 和 sslstream。
    猜你喜欢
    • 2016-05-06
    • 2017-11-01
    • 2021-09-19
    • 2019-03-31
    • 2018-08-01
    • 2020-06-02
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    相关资源
    最近更新 更多