1

我从这里使用了一个模板来编写SSL 隧道。但它仅适用于HTTPS连接。我的任务包括读取和编辑通过隧道传递的数据。我试图通过SSLServerSocketFactory对此进行解密。但是我遇到了这个错误。

我在 keytool 的帮助下创建了一个密钥:

keytool -genkeypair -dname "cn=Mark Jones, ou=JavaSoft, o=Sun, c=US" -alias business -keypass kpi135 -keystore mySrvKeystore2 -storepass ab987c -validity 365

1、如何支持HTTP协议?

2. 如何在 SSL 上解密和编辑数据?

我在 Mozilla Firefox 浏览器中使用代理并加载https://google.com/页面。我错过了通过localhost:9798上的 myServerTest 的流量。

方案:
client [request] >> myServerTest (localhost) >> Internet >> myServerTest (localhost) >> client [response]

package sample;

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


public class ServerTest extends Thread {

    Boolean stateSSL = false;  // whether the socket is created with SSL
    Integer port = 9798;

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

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


    public ServerSocket createSLLSocket() {
        try {
            // comment block for create non-ssl connection
            // and uncomment return null;
            System.setProperty("javax.net.ssl.trustStore", "D:\\OnlyTemp\\mySrvKeystore2");
            System.setProperty("javax.net.ssl.trustStorePassword", "ab987c");
            SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
            ServerSocket sslserversocket = sslserversocketfactory.createServerSocket(port);
            ServerSocket acceptSocket = sslserversocket;
            System.out.println("++ created [with] ssl server");
            return acceptSocket;

            //return null;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public void run() {
        System.out.println("++ server ServerTest run ");

        try {
            Socket acceptSocket = null;
            ServerSocket serverSSLSocket = createSLLSocket();
            ServerSocket serverSocket = null;
            if (serverSSLSocket != null) {
                stateSSL = true;
            } else {
                System.out.println("-- created [without] ssl server");
                serverSocket = new ServerSocket(port);
                stateSSL = false;
            }
            if (stateSSL == false) {
                System.out.println("-- server [stateSSL] false");
                try {
                    while ((acceptSocket = serverSocket.accept()) != null) {
                        (new Handler(acceptSocket, stateSSL)).start();
                    }
                } catch (Exception e) {
                    e.printStackTrace();  // TODO: implement catch
                }
            } else {
                try {
                    while ((acceptSocket = serverSSLSocket.accept()) != null) {
                        (new Handler(acceptSocket, stateSSL)).start();
                    }
                } catch (Exception 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 final Boolean stateSSL;
        private boolean previousWasR = false;

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

        @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) {
                // hide temp
                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");
        }

    }
}
4

0 回答 0