Implementing a simple HTTPS proxy application with Java?

I am writing a simple HTTPS proxy program with Java for educational purposes. My program listens on the port (say 7443 ) for incoming HTTPS requests from the browser (say Firefox ), analyzes the request and redirects it to the desired destination (say https://www.comodo.com ).

Firefox proxy settings are configured to use my port for SSL connections ( 127.0.0.1 : 7443 ).

My code is short and simple:

 static // initializer { System.setProperty("javax.net.ssl.keyStore", "MyKeyStore"); System.setProperty("javax.net.ssl.keyStorePassword", "password"); } SSLServerSocketFactory ssFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); try { SSLServerSocket listener = (SSLServerSocket) ssFactory.createServerSocket(port, 64); listener.setUseClientMode(false); listener.setWantClientAuth(false); listener.setNeedClientAuth(false); SSLSocket connection = (SSLSocket) listener.accept(); browser.startHandshake(); /* <<== Exception throws at this line */ } catch (IOException ex) { ex.printStackTrace(System.err); } 

But I caught the following exception:

  javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? 

An exception indicates that the connection may be plain text, but only HTTPS connections from Firefox are configured to use this port. I registered that Firefox sends to my application which:

 CONNECT www.comodo.com:443 HTTP/1.1 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0 Proxy-Connection: keep-alive Connection: keep-alive Host: www.comodo.com 

Firefox says the palin text, and I think CONNECT is a SOCKS command (I'm not sure though), where I did not set anything in Firefox SOCKS settings. Below is a screenshot of the Firefox proxy settings:

Firefox proxy settings

What am I missing here ?! What do I need to do to make this work with Firefox or any other browser ?!

----------------------------------------------- --- ----------------------------

For those who think that this is a duplicate of another question , and that they answered it in another, I must say: "Yes, both questions have roots in a similar problem, but the only answer in the quoted question is sent when using SSL sockets, which turned out to be deceptive and led to this new question.Therefore, although they are aimed at a similar problem, this question shows a completely different and yet misleading way to solve the problem, and therefore it can serve as a useful guide for future individuals facing Second problem.

+6
source share
2 answers

Get rid of all SSL. Just process the incoming CONNECT command, make a plaintext connection to the upstream server, and then start copying the bytes. The browser and server will speak SSL, but you do not need to.

+6
source

Your setup uses HTTP tunneling, where the initial request sent by the proxy is not SSL encrypted; since an SSL enabled socket is awaiting SSL confirmation, it throws an exception.

In this mechanism, the client requests an HTTP proxy server to forward a TCP connection to the desired destination using the "CONNECT" HTTP method. Then the server proceeds to connect on behalf of the client. Once the connection is established by the server, the proxy continues to proxy the TCP stream to and from the client. Please note that only the initial connection request - HTTP - after which the server simply proxies the established TCP connection.

For more information, see the HTTP Tunneling page. To see this in action, you can start from the netcat server and install a Firefox proxy to point to this port:

 nc -l 8000 

Now in Firefox, enter https://www.google.com and review the output of nc:

 CONNECT www.google.com:443 HTTP/1.1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Proxy-Connection: keep-alive Connection: keep-alive Host: www.google.com 

And it is completely clear text . The bottom of the diagram shows how the Firefox proxy is waiting for a connection.

enter image description here

+3
source

Source: https://habr.com/ru/post/944209/


All Articles