Java的HTTPS代理(使用https.proxyPort和https.proxyHost)(Ja

2019-09-01 19:33发布

我正在做一个依靠设置一个Java应用程序http.proxyPorthttp.proxyHost 。 有两种方法:一种是正规程序,另一种是代理。 我有一个简单的socket监听器上运行http.proxyPort (我控制)。 它的那样简单

while (true) {
    try {
    Socket connection = server.accept();

    Handler handler = new Handler(connection);
    handler.start();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

所以每当“处理1”发出HTTP请求 - 像

URL yahoo = new URL("http://www.google.ca/");
URLConnection yc = yahoo.openConnection();
System.out.println(yc.getClass().getName());
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));

它通过代理。 现在,如果客户端使用HTTPS协议是什么? 像改用https://google.ca ? 有一个属性https.proxyPorthttps.proxyHost ,但我从字面上一直试图个月(开启和关闭,这不是太重要),没有运气。 我读了一堆线程(我将列出一些在年底,所以你知道我做了什么)。

到目前为止,我最近尝试:服务器

try {
    System.setProperty("javax.net.ssl.keyStore", "test.jks");
    System.setProperty("javax.net.ssl.keyStorePassword", "2520xe");

    SSLServerSocketFactory sslserversocketfactory =
            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
    SSLServerSocket sslserversocket =
            (SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
    System.out.println("Ready");
    SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

    InputStream inputstream = sslsocket.getInputStream();
    InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
    BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

    OutputStream toClient = sslsocket.getOutputStream();
    toClient.write(("HTTP/1.0 200 Connection established\n" +
            "Content-Length: " + "Shut down!".getBytes().length
                                     + "\r\n").getBytes("utf-8"));
    toClient.write("Shut down!".getBytes("utf-8"));
    toClient.close();
} catch (Exception exception) {
    exception.printStackTrace();
}

客户

try {
    System.setProperty("https.proxyHost", "127.0.0.1");
    System.setProperty("https.proxyPort", "9999");
    URL yahoo = new URL("https://www.google.ca/");
    URLConnection yc = yahoo.openConnection();
    System.out.println(yc.getClass().getName());
    BufferedReader in = new BufferedReader(
                new InputStreamReader(
                yc.getInputStream()));
    String inputLine;

    while ((inputLine = in.readLine()) != null) 
    System.out.println(inputLine);
    in.close();
} catch (Exception ex) {
    ex.printStackTrace();
}

而我得到这个错误javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection? 我GOOGLE了,但与一些邮件的东西,而不是走了过来。

基本上,我需要创建一个Java代理服务器,这是由设置成客户端https.proxyPorthttps.proxyHost标志,并且可以将数据发送回客户端应用程序,这可能不以任何方式(修改它只是使用URL connection = new URL("https://...")

几个我试过的网站...

  • 创建接受一个Java代理服务器HTTPS
  • http://stilius.net/java/java_ssl.php
  • 有其他关于得到Java来接受所有证书的东西,但我找不到任何的联系。 我的代码,但我遇到了比我现在在做的事情更多的错误,但如果它帮助我可以包括它(我最初没有,因为这已经是一个长期的问题)

Answer 1:

作为auntyellow说:你不需要做任何SSL-摆弄自己。 基本上HTTPS的代理约双方之间转发二进制数据。

举选秀luotonen的Web代理穿隧01.txt :

  CLIENT -> SERVER SERVER -> CLIENT -------------------------------------- ----------------------------------- CONNECT home.netscape.com:443 HTTP/1.0 User-agent: Mozilla/4.0 <<< empty line >>> HTTP/1.0 200 Connection established Proxy-agent: Netscape-Proxy/1.1 <<< empty line >>> <<< data tunneling to both directions begins >>> 

所以基本上你需要确保你信任你的客户,足以从代理防火墙的位置连接到指定的主机和端口。 由于这种普遍做法是允许的端口限制在443,拒绝连接到本地主机,并从“不可信”的政党。

这是一个“简单”的服务,这也是可以作为https.proxy如果你不服气喷在Java中:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created for http://stackoverflow.com/q/16351413/1266906.
 */
public class Server extends Thread {

    public static void main(String[] args) {
        (new Server()).run();
    }

    public Server() {
        super("Server Thread");
    }

    @Override
    public void run() {
        try (ServerSocket serverSocket = new ServerSocket(9999)) {
            Socket socket;
            try {
                while ((socket = serverSocket.accept()) != null) {
                    (new Handler(socket)).start();
                }
            } catch (IOException e) {
                e.printStackTrace();  // TODO: implement catch
            }
        } catch (IOException e) {
            e.printStackTrace();  // TODO: implement catch
            return;
        }
    }

    public static class Handler extends Thread {
        public static final Pattern CONNECT_PATTERN = Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])",
                                                                      Pattern.CASE_INSENSITIVE);
        private final Socket clientSocket;
        private boolean previousWasR = false;

        public Handler(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                String request = readLine(clientSocket);
                System.out.println(request);
                Matcher matcher = CONNECT_PATTERN.matcher(request);
                if (matcher.matches()) {
                    String header;
                    do {
                        header = readLine(clientSocket);
                    } while (!"".equals(header));
                    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(clientSocket.getOutputStream(),
                                                                                   "ISO-8859-1");

                    final Socket forwardSocket;
                    try {
                        forwardSocket = new Socket(matcher.group(1), Integer.parseInt(matcher.group(2)));
                        System.out.println(forwardSocket);
                    } catch (IOException | NumberFormatException e) {
                        e.printStackTrace();  // TODO: implement catch
                        outputStreamWriter.write("HTTP/" + matcher.group(3) + " 502 Bad Gateway\r\n");
                        outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
                        outputStreamWriter.write("\r\n");
                        outputStreamWriter.flush();
                        return;
                    }
                    try {
                        outputStreamWriter.write("HTTP/" + matcher.group(3) + " 200 Connection established\r\n");
                        outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
                        outputStreamWriter.write("\r\n");
                        outputStreamWriter.flush();

                        Thread remoteToClient = new Thread() {
                            @Override
                            public void run() {
                                forwardData(forwardSocket, clientSocket);
                            }
                        };
                        remoteToClient.start();
                        try {
                            if (previousWasR) {
                                int read = clientSocket.getInputStream().read();
                                if (read != -1) {
                                    if (read != '\n') {
                                        forwardSocket.getOutputStream().write(read);
                                    }
                                    forwardData(clientSocket, forwardSocket);
                                } else {
                                    if (!forwardSocket.isOutputShutdown()) {
                                        forwardSocket.shutdownOutput();
                                    }
                                    if (!clientSocket.isInputShutdown()) {
                                        clientSocket.shutdownInput();
                                    }
                                }
                            } else {
                                forwardData(clientSocket, forwardSocket);
                            }
                        } finally {
                            try {
                                remoteToClient.join();
                            } catch (InterruptedException e) {
                                e.printStackTrace();  // TODO: implement catch
                            }
                        }
                    } finally {
                        forwardSocket.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();  // TODO: implement catch
            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();  // TODO: implement catch
                }
            }
        }

        private static void forwardData(Socket inputSocket, Socket outputSocket) {
            try {
                InputStream inputStream = inputSocket.getInputStream();
                try {
                    OutputStream outputStream = outputSocket.getOutputStream();
                    try {
                        byte[] buffer = new byte[4096];
                        int read;
                        do {
                            read = inputStream.read(buffer);
                            if (read > 0) {
                                outputStream.write(buffer, 0, read);
                                if (inputStream.available() < 1) {
                                    outputStream.flush();
                                }
                            }
                        } while (read >= 0);
                    } finally {
                        if (!outputSocket.isOutputShutdown()) {
                            outputSocket.shutdownOutput();
                        }
                    }
                } finally {
                    if (!inputSocket.isInputShutdown()) {
                        inputSocket.shutdownInput();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();  // TODO: implement catch
            }
        }

        private String readLine(Socket socket) throws IOException {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int next;
            readerLoop:
            while ((next = socket.getInputStream().read()) != -1) {
                if (previousWasR && next == '\n') {
                    previousWasR = false;
                    continue;
                }
                previousWasR = false;
                switch (next) {
                    case '\r':
                        previousWasR = true;
                        break readerLoop;
                    case '\n':
                        break readerLoop;
                    default:
                        byteArrayOutputStream.write(next);
                        break;
                }
            }
            return byteArrayOutputStream.toString("ISO-8859-1");
        }
    }
}


Answer 2:

为HTTPS协议默认的Java SE7执行的URLConnection的使用参数
https.proxyHosthttps.proxyPort

添加到Tomcat:

-Dhttps.proxyHost = “192.168.121.31” -Dhttps.proxyPort = “3128”



文章来源: Java https proxy (using https.proxyPort and https.proxyHost)
标签: java https proxy