Proxy 代理服务器上的HTTPS连接
是否可以通过代理服务器进行HTTPS连接?如果是,什么样的代理服务器允许这样做 使用TLS/SSL复制(HTTPS中的S)可确保您与正在联系的服务器之间没有窃听者,即没有代理。通常,通过代理打开TCP连接。在这种情况下,代理将无法缓存、读取或修改任何请求/响应,因此毫无用处 如果希望代理能够读取信息,可以采用以下方法:Proxy 代理服务器上的HTTPS连接,proxy,https,Proxy,Https,是否可以通过代理服务器进行HTTPS连接?如果是,什么样的代理服务器允许这样做 使用TLS/SSL复制(HTTPS中的S)可确保您与正在联系的服务器之间没有窃听者,即没有代理。通常,通过代理打开TCP连接。在这种情况下,代理将无法缓存、读取或修改任何请求/响应,因此毫无用处 如果希望代理能够读取信息,可以采用以下方法: 客户端启动HTTPS会话 代理透明地拦截连接并 返回一个临时生成的(可能是 弱)证书Ka, 由证书颁发机构签署 这是我们无条件信任的 客户 代理启动到目标的HTTPS会话 代理验
请注意,现代网站和浏览器可以采用或击败这种方法。据我所知,您需要在代理上使用HTTP CONNECT查询。这将把请求连接转换为透明的TCP/IP隧道
因此,您需要知道您使用的代理服务器是否支持此协议。如果仍然感兴趣,下面是一个类似问题的答案: 回答问题的第二部分: 如果是,什么样的代理服务器 允许这样吗
开箱即用,大多数代理服务器将配置为只允许HTTPS连接到端口443,因此带有自定义端口的HTTPS URI将无法工作。这通常是可配置的,具体取决于代理服务器。例如,Squid和TinyProxy支持这一点。您可以使用中间人技术和动态SSL生成来实现这一点。看一看-它是一个基于Python、支持SSL的MITM代理。通过SSH隧道传输HTTPS(linux版本): 在本地主机上执行的所有操作。 然后:
下面是我的完整Java代码,它支持使用SOCKS代理的HTTP和HTTPS请求
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
/**
* How to send a HTTP or HTTPS request via SOCKS proxy.
*/
public class ClientExecuteSOCKS {
public static void main(String[] args) throws Exception {
Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new MyHTTPConnectionSocketFactory())
.register("https", new MyHTTPSConnectionSocketFactory(SSLContexts.createSystemDefault
()))
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);
try (CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.build()) {
InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234);
HttpClientContext context = HttpClientContext.create();
context.setAttribute("socks.address", socksaddr);
HttpHost target = new HttpHost("www.example.com/", 80, "http");
HttpGet request = new HttpGet("/");
System.out.println("Executing request " + request + " to " + target + " via SOCKS " +
"proxy " + socksaddr);
try (CloseableHttpResponse response = httpclient.execute(target, request, context)) {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity(), StandardCharsets
.UTF_8));
}
}
}
static class MyHTTPConnectionSocketFactory extends PlainConnectionSocketFactory {
@Override
public Socket createSocket(final HttpContext context) throws IOException {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}
}
static class MyHTTPSConnectionSocketFactory extends SSLConnectionSocketFactory {
public MyHTTPSConnectionSocketFactory(final SSLContext sslContext) {
super(sslContext);
}
@Override
public Socket createSocket(final HttpContext context) throws IOException {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}
}
}
import java.io.IOException;
导入java.net.InetSocketAddress;
导入java.net.Proxy;
导入java.net.Socket;
导入java.nio.charset.StandardCharset;
导入org.apache.http.HttpHost;
导入org.apache.http.client.methods.CloseableHttpResponse;
导入org.apache.http.client.methods.HttpGet;
导入org.apache.http.client.protocol.HttpClientContext;
导入org.apache.http.config.Registry;
导入org.apache.http.config.RegistryBuilder;
导入org.apache.http.conn.socket.ConnectionSocketFactory;
导入org.apache.http.conn.socket.PlainConnectionSocketFactory;
导入org.apache.http.conn.ssl.SSLConnectionSocketFactory;
导入org.apache.http.impl.client.CloseableHttpClient;
导入org.apache.http.impl.client.HttpClients;
导入org.apache.http.impl.conn.poolighttpclientconnectionmanager;
导入org.apache.http.protocol.HttpContext;
导入org.apache.http.ssl.SSLContexts;
导入org.apache.http.util.EntityUtils;
导入javax.net.ssl.SSLContext;
/**
*如何通过SOCKS代理发送HTTP或HTTPS请求。
*/
公共类客户服务中心{
公共静态void main(字符串[]args)引发异常{
Registry reg=RegistryBuilder.create()
.register(“http”,新的MyHTTPConnectionSocketFactory())
.register(“https”,新的MyHTTPSConnectionSocketFactory(SSLContexts.createSystemDefault
()))
.build();
PoolightPClientConnectionManager cm=新的PoolightPClientConnectionManager(reg);
try(CloseableHttpClient-httpclient=HttpClients.custom()
.setConnectionManager(cm)
.build()){
InetSocketAddress socksaddr=新的InetSocketAddress(“mysockshost”,1234);
HttpClientContext=HttpClientContext.create();
context.setAttribute(“socks.address”,socksaddr);
HttpHost target=新的HttpHost(“www.example.com/”,80,“http”);
HttpGet请求=新的HttpGet(“/”);
System.out.println(“通过SOCKS执行请求”+请求+”到“+目标+”+
“代理人”+socksaddr);
try(CloseableHttpResponse-response=httpclient.execute(目标、请求、上下文)){
System.out.println(“--------------------------------------------------------”;
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity(),StandardCharset
.UTF_(8));
}
}
}
静态类MyHTTPConnectionSocketFactory扩展了PlainConnectionSocketFactory{
@凌驾
公共套接字createSocket(最终HttpContext上下文)引发IOException{
InetSocketAddress socksaddr=(InetSocketAddress)context.getAttribute(“socks.address”);
代理代理=新代理(Proxy.Type.SOCKS,socksaddr);
返回新套接字(代理);
}
}
静态类MyHTTPSConnectionSocketFactory扩展了SSLConnectionSocketFactory{
公共MyHTTPSConnectionSocketFactory(最终SSLContext SSLContext){
超级(sslContext);
}
@凌驾
公共套接字createSocket(最终HttpContext上下文)引发IOException{
InetSocketAddress socksaddr=(InetSocketAddress)context.getAttribute(“socks.address”);
代理代理=新代理(Proxy.Type.SOCKS,socksaddr);
返回新套接字(代理);
}
}
}
简单的回答是:这是可能的,可以使用特殊的HTTP代理或SOCKS代理完成
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
/**
* How to send a HTTP or HTTPS request via SOCKS proxy.
*/
public class ClientExecuteSOCKS {
public static void main(String[] args) throws Exception {
Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new MyHTTPConnectionSocketFactory())
.register("https", new MyHTTPSConnectionSocketFactory(SSLContexts.createSystemDefault
()))
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);
try (CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.build()) {
InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234);
HttpClientContext context = HttpClientContext.create();
context.setAttribute("socks.address", socksaddr);
HttpHost target = new HttpHost("www.example.com/", 80, "http");
HttpGet request = new HttpGet("/");
System.out.println("Executing request " + request + " to " + target + " via SOCKS " +
"proxy " + socksaddr);
try (CloseableHttpResponse response = httpclient.execute(target, request, context)) {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity(), StandardCharsets
.UTF_8));
}
}
}
static class MyHTTPConnectionSocketFactory extends PlainConnectionSocketFactory {
@Override
public Socket createSocket(final HttpContext context) throws IOException {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}
}
static class MyHTTPSConnectionSocketFactory extends SSLConnectionSocketFactory {
public MyHTTPSConnectionSocketFactory(final SSLContext sslContext) {
super(sslContext);
}
@Override
public Socket createSocket(final HttpContext context) throws IOException {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}
}
}
首先也是最重要的,HTTPS使用SSL/TLS,从设计上讲,它通过在不安全的通信通道上建立安全的通信通道来确保端到端的安全性。如果HTTP代理能够看到
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
/**
* How to send a HTTP or HTTPS request via SOCKS proxy.
*/
public class ClientExecuteSOCKS {
public static void main(String[] args) throws Exception {
Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new MyHTTPConnectionSocketFactory())
.register("https", new MyHTTPSConnectionSocketFactory(SSLContexts.createSystemDefault
()))
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);
try (CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.build()) {
InetSocketAddress socksaddr = new InetSocketAddress("mysockshost", 1234);
HttpClientContext context = HttpClientContext.create();
context.setAttribute("socks.address", socksaddr);
HttpHost target = new HttpHost("www.example.com/", 80, "http");
HttpGet request = new HttpGet("/");
System.out.println("Executing request " + request + " to " + target + " via SOCKS " +
"proxy " + socksaddr);
try (CloseableHttpResponse response = httpclient.execute(target, request, context)) {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity(), StandardCharsets
.UTF_8));
}
}
}
static class MyHTTPConnectionSocketFactory extends PlainConnectionSocketFactory {
@Override
public Socket createSocket(final HttpContext context) throws IOException {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}
}
static class MyHTTPSConnectionSocketFactory extends SSLConnectionSocketFactory {
public MyHTTPSConnectionSocketFactory(final SSLContext sslContext) {
super(sslContext);
}
@Override
public Socket createSocket(final HttpContext context) throws IOException {
InetSocketAddress socksaddr = (InetSocketAddress) context.getAttribute("socks.address");
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr);
return new Socket(proxy);
}
}
}