Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect to HTTPS proxy?

I'm trying to connect to HTTPS server through proxy using sockets. As far as I know when using HTTP proxy one should connect socket to it and then interact with it as it is the real server. With HTTP this approach works, but with HTTPS isn't. Why?

Here's simple program that connects to HTTPS server

using System;
using System.Text;
using System.Net.Sockets;
using System.Net.Security;

namespace SslTcpClient
{
    public class SslTcpClient
    {
        public static void Main(string[] args)
        {
            string host = "encrypted.google.com";
            string proxy = "127.0.0.1";//host;
            int proxyPort = 8888;//443;

            // Connect socket
            TcpClient client = new TcpClient(proxy, proxyPort);

            // Wrap in SSL stream
            SslStream sslStream = new SslStream(client.GetStream());
            sslStream.AuthenticateAsClient(host);

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

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

            client.Close();
            Console.ReadKey();
        }
    }
}

It successfully connects when proxy = host and proxyPort = 443. But when I set them to 127.0.0.1:8888 (fiddler proxy on localhost) it doesn't work. Program hangs at sslStream.AuthenticateAsClient(host); Why? Fiddler supports HTTPS (browsers are able to connect through it).

P.S. No, I can't use HttpWebRequest in my case.

like image 517
Poma Avatar asked Aug 04 '11 11:08

Poma


People also ask

How do I connect to a proxy?

To set up a proxy server for a VPN connectionSelect the Start button, then select Settings > Network & Internet > VPN. Select the VPN connection, then select Advanced options. Under VPN proxy settings, select the type of proxy setup you want to use, then enter the proxy server information for that VPN connection.

Is there a HTTPS proxy?

SSL proxy is also called an HTTPS proxy, the abbreviation meaning Hypertext Transfer Protocol over SSL. To put it briefly, an HTTPS proxy is a proxy that uses the HTTP protocol over SSL. The HTTPS protocol has today become the standard for most websites and online services.

Can proxy server read HTTPS?

It depends on if the proxy works on the HTTP level or the TCP level. If it is an HTTP proxy, then in order for the HTTP request to be read, it has to be decoded by the proxy. In other words, they would be able to read the traffic, but the traffic to and from would be encrypted.


1 Answers

Managed to solve it myself. Here's the solution:

using System;
using System.Text;
using System.Net.Sockets;
using System.Net.Security;

namespace SslTcpClient
{
    public class SslTcpClient
    {
        public static void Main(string[] args)
        {
            string host = "encrypted.google.com";
            string proxy = "127.0.0.1";//host;
            int proxyPort = 8888;//443;

            byte[] buffer = new byte[2048];
            int bytes;

            // Connect socket
            TcpClient client = new TcpClient(proxy, proxyPort);
            NetworkStream stream = client.GetStream();

            // Establish Tcp tunnel
            byte[] tunnelRequest = Encoding.UTF8.GetBytes(String.Format("CONNECT {0}:443  HTTP/1.1\r\nHost: {0}\r\n\r\n", host));
            stream.Write(tunnelRequest , 0, tunnelRequest.Length);
            stream.Flush();

            // Read response to CONNECT request
            // There should be loop that reads multiple packets
            bytes = stream.Read(buffer, 0, buffer.Length);
            Console.Write(Encoding.UTF8.GetString(buffer, 0, bytes));

            // Wrap in SSL stream
            SslStream sslStream = new SslStream(stream);
            sslStream.AuthenticateAsClient(host);

            // Send request
            byte[] request = Encoding.UTF8.GetBytes(String.Format("GET https://{0}/  HTTP/1.1\r\nHost: {0}\r\n\r\n", host));
            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 != 0);

            client.Close();
            Console.ReadKey();
        }
    }
}
like image 153
Poma Avatar answered Sep 28 '22 02:09

Poma