简体   繁体   English

如何通过SslStream和TcpClient将有效的HTTPS请求发送到Web服务

[英]How to send valid HTTPS requests to a web service via SslStream and TcpClient

I'm essentially attempting to setup a HTTPS client I can use for automated testing APIs and other web services I'm developing. 我实质上是在尝试设置一个HTTPS客户端,该客户端可用于我正在开发的自动化测试API和其他Web服务。 I'm familiar with using sockets, but not so much with using SSL/TLS in code. 我对使用套接字很熟悉,但是对在代码中使用SSL / TLS却不太了解。 I've started by attempting to setup a client that sends an HTTP request to google.com with the following header: GET / HTTP/1.1 我首先尝试设置一个客户端,该客户端使用以下标头向google.com发送HTTP请求: GET / HTTP/1.1

The idea is to receive a basic HTTP response from Google, via an encrypted connection of course. 这个想法是通过加密连接从Google接收基本的HTTP响应。 This is really easy when using unencrypted HTTP - I can even telnet into google over port 80 and enter GET / HTTP/1.1 and I receive a nice HTTP response header and HTML payload. 使用未加密的HTTP时,这真的很容易-我什至可以通过端口80 telnet到google中,然后输入GET / HTTP/1.1 ,我会收到一个不错的HTTP响应标头和HTML有效负载。 Implementing the C/C# code for making unencrypted HTTP requests is also not very difficult. 实现C / C#代码以发出未加密的HTTP请求也不是很困难。 It's SSL that is giving me a difficult time. SSL使我很难受。

Using the code below (full sample found at https://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-3 ), which is an almost identical implementation to what is provided by MSDN for reference, I can successfully connect to google.com and validate the server certificate: 使用下面的代码(完整的示例位于https://msdn.microsoft.com/zh-cn/library/system.net.security.sslstream.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet -3 ),与MSDN提供的参考几乎完全相同,因此我可以成功连接到google.com并验证服务器证书:

        // Create a TCP/IP client socket.
        // machineName is the host running the server application.
        TcpClient client = new TcpClient(machineName, 443);
        Console.WriteLine("Client connected.");
        // Create an SSL stream that will close the client's stream.
        SslStream sslStream = new SslStream(
            client.GetStream(),
            false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate),
            null
            );
        // The server name must match the name on the server certificate.
        try
        {
            sslStream.AuthenticateAsClient(serverName);
        }
        catch (AuthenticationException e)
        {
            Console.WriteLine("Exception: {0}", e.Message);
            if (e.InnerException != null)
            {
                Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
            }
            Console.WriteLine("Authentication failed - closing the connection.");
            client.Close();
            return;
        }

The issue is when the following code executes, the ReadMessage(sslStream) instruction hangs, as in I don't receive a response for a very long time, and when the response finally comes in it is an empty string: 问题是执行以下代码时,ReadMessage(sslStream)指令挂起,因为很长一段时间我都没有收到响应,而当响应最终出现时,它是一个空字符串:

        // Encode a test message into a byte array.
        // Signal the end of the message using the "<EOF>".
        byte[] messsage = Encoding.UTF8.GetBytes("GET / HTTP/1.1<EOF>");
        // Send hello message to the server. 
        sslStream.Write(messsage);
        sslStream.Flush();
        // Read message from the server.
        string serverMessage = ReadMessage(sslStream);
        Console.WriteLine("Server says: {0}", serverMessage);

Therefore, I'm unable to receive the HTTP response I was looking for (or anything at all) when I make this request over a secure socket connection. 因此,通过安全套接字连接发出此请求时,我无法收到我正在寻找的HTTP响应(或任何其他响应)。 The idea in the long run is to start using this client to send customized HTTP requests to my own APIs and web services, but I certainly cannot do that if I cannot even get a generic response from google.com. 从长远来看,这个想法是开始使用此客户端向我自己的API和Web服务发送自定义的HTTP请求,但是,即使我什至无法从google.com上获得通用响应,我也肯定不会这样做。 Does anyone have an idea why the ReadMessage() function is timing out or otherwise providing no response? 有谁知道为什么ReadMessage()函数超时或不提供任何响应? The sample code seems very straightforward so I'm having a hard time understanding what I'm doing wrong. 该示例代码看起来非常简单,因此我很难理解自己在做什么。

One thing that immediately caught my attention is that the Microsoft example does not provide the "count" argument for sslStream.Write() , which I believe may be related to your issue. 立即引起我注意的一件事是,Microsoft示例未为sslStream.Write()提供“ count”参数,我认为这可能与您的问题有关。 Also note, ReadMessage() appears to be a function you have not provided a definition for. 还要注意, ReadMessage()似乎是您未提供定义的函数。 Without knowing what ReadMessage() is doing specifically, the exact cause of your problem cannot be determined. 如果不知道ReadMessage()具体在做什么,则无法确定问题的确切原因。 I modified the provided code for sending a HTTPS request and reading the response. 我修改了提供的代码,以发送HTTPS请求和读取响应。 It seems to work fine with sites I've tried thus far. 到目前为止,我尝试过的网站似乎都可以正常工作。

        // Send request
        byte[] buffer = new byte[2048];
        int bytes;
        byte[] request = Encoding.UTF8.GetBytes(String.Format("GET https://{0}/  HTTP/1.1\r\nHost: {0}\r\n\r\n", serverName));
        sslStream.Write(request, 0, request.Length);
        sslStream.Flush();

        // Read response
        do
        {
            bytes = sslStream.Read(buffer, 0, buffer.Length);
            Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes));
        } while (bytes == 2048);

As a side note, I also noticed sslStream.AuthenticateAsClient(serverName); 另外,我还注意到sslStream.AuthenticateAsClient(serverName); which certainly works for many web services; 当然适用于许多Web服务; however, I've had issues with that particular overload when accessing sites that strictly use TLS1.2. 但是,在访问严格使用TLS1.2的网站时,我遇到了特别重载的问题。 Try sslStream.AuthenticateAsClient(serverName,null,SslProtocols.Tls12,false); 尝试sslStream.AuthenticateAsClient(serverName,null,SslProtocols.Tls12,false); if you want to enable support for strictly TLS1.2 agents. 如果要启用对严格的TLS1.2代理的支持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM