我从这里使用了一个模板来编写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");
}
}
}