是否可以通过代理服务器进行HTTPS连接?如果是,哪种代理服务器允许这种情况?
发布于 2016-11-30 17:55:21
简短的答案是:这是可能的,并且可以使用特殊的HTTP代理或SOCKS代理来完成。
首先,HTTPS使用SSL/TLS,它通过在不安全的通信通道上建立安全的通信通道来确保端到端的安全性。如果HTTP代理能够看到内容,那么它就是一个中间人窃听者,这就违背了SSL/TLS的目标。因此,如果我们想要通过普通的HTTP代理进行代理,那么一定会有一些技巧在起作用。
诀窍是,我们使用一个名为CONNECT
的特殊命令将HTTP代理转换为TCP代理。并不是所有的HTTP代理都支持这个特性,但是现在很多都支持了。TCP代理看不到以明文传输的HTTP内容,但这并不影响它来回转发数据包的能力。这样,客户端和服务器就可以在代理的帮助下相互通信。这是代理HTTPS数据的安全方法。
还有一种不安全的方式,HTTP代理变成了中间人。它接收客户端发起的连接,然后发起另一个到真实服务器的连接。在实现良好的SSL/TLS中,客户端将被通知代理不是真正的服务器。因此,客户端必须通过忽略警告来信任代理才能正常工作。在此之后,代理简单地解密来自一个连接的数据,重新加密并将其提供给另一个连接。
最后,我们当然可以通过SOCKS代理来代理HTTPS,因为SOCKS代理在较低的级别工作。您可能认为SOCKS代理既是TCP代理又是UDP代理。
发布于 2009-02-05 15:56:08
据我所知,您需要在代理上使用HTTP连接查询。这会将请求连接转换为透明的TCP/IP隧道。
所以你需要知道你使用的代理服务器是否支持这个协议。
发布于 2015-09-03 15:56:00
下面是使用SOCKS代理支持HTTP和HTTPS请求的完整Java代码。
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://stackoverflow.com/questions/516323
复制相似问题