6

我正在用 Java 编写一个简单的 HTTPS 代理程序,用于教育目的。我的程序在端口(例如7443)上侦听来自浏览器(例如Firefox)的传入 HTTPS 请求,解析请求并将其转发到所需的目的地(例如https://www.comodo.com)。

Firefox 的代理设置设置为使用我的端口进行 SSL 连接 ( 127.0.0.1 : 7443)。

我的代码简短而简单:

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);
}

但我发现了以下异常:

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

异常表示连接可以是纯文本的,但只有来自 Firefox 的 HTTPS 连接设置为使用此端口。我已经记录了 Firefox 发送到我的应用程序的内容,即:

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 正在谈论 palin-text,我认为CONNECT是一个 SOCKS 命令(虽然我不确定),但我没有在 Firefox 的 SOCKS 设置中设置任何内容。下面是 Firefox 代理设置的截图:

火狐代理设置

我在这里想念什么?!我需要做些什么才能使它与 Firefox 或任何其他浏览器一起工作?!

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

对于那些认为这是另一个问题的重复并且已经在另一个问题中得到回答的人,我不得不说:是的,这两个问题都源于一个类似的问题,但所引用问题中的唯一答案是使用 SSL Sockets原来是误导并导致了这个新问题。因此,尽管他们针对的是类似的问题,但这个问题显示了解决问题的完全不同但误导性的路径,因此它可以为未来面临此类问题的人提供有用的指导。

4

2 回答 2

6

摆脱所有 SSL。只需处理传入的 CONNECT 命令,与上游服务器建立明文连接,然后开始复制字节。浏览器和服务器会使用 SSL,但您根本不需要。

于 2013-05-04T18:25:36.410 回答
3

您的设置使用 HTTP 隧道,其中发送到代理的初始请求经过SSL 加密;由于启用 SSL 的套接字需要 SSL 握手,因此它会引发异常。

在这种机制中,客户端使用“CONNECT”HTTP 方法请求 HTTP 代理服务器将 TCP 连接转发到所需的目的地。然后服务器继续代表客户端建立连接。一旦服务器建立了连接,代理服务器将继续代理与客户端之间的 TCP 流。请注意,只有初始连接请求是 HTTP - 之后,服务器只是代理已建立的 TCP 连接。

您可以在HTTP Tunneling wiki 页面了解更多信息。要查看实际情况,您可以启动 netcat 服务器并将 Firefox 代理设置为指向该端口:

nc -l 8000

现在在 Firefox 中输入https://www.google.com,然后检查 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

这完全是明文。下图演示了Firefox代理如何进行通信。

在此处输入图像描述

于 2013-06-06T05:31:33.673 回答