gpt4 book ai didi

java - HttpClient : ssl handshake on every request

转载 作者:搜寻专家 更新时间:2023-11-01 03:24:39 26 4
gpt4 key购买 nike

我使用静态 HttpClient,它在 https 上运行非常慢。我添加了 -Djavax.net.debug=ssl 并发现再次为每个 https 请求启动握手。看起来它不能重用旧 session ,但我找不到原因。

9007199254743735, setSoTimeout(0) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
9007199254743735, setSoTimeout(0) called
%% No cached client session
*** ClientHello, SSLv3
...
%% Didn't cache non-resumable client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
...
Is initial handshake: true

顺便说一句。在我在此主机上遇到另一个问题之前:“收到致命警报:bad_record_mac”,通过仅允许 SSLv3 解决了这个问题

UPD1: HttpClient 初始化代码

    final SSLContext sslCtx;
sslCtx = SSLContext.getInstance("SSL");
sslCtx.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] cert,
String authType) {
}

@Override
public void checkServerTrusted(X509Certificate[] cert,
String authType) {
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}}, null);

X509HostnameVerifier verifier = new X509HostnameVerifier() {
@Override
public void verify(String string, SSLSocket ssls) throws IOException {
}

@Override
public void verify(String string, X509Certificate xc) throws SSLException {
}

@Override
public void verify(String string, String[] strings, String[] strings1) throws SSLException {
}

@Override
public boolean verify(String string, SSLSession ssls) {
return true;
}
};
final SSLSocketFactory socketFactory = new SSLv3SocketFactory(sslCtx, verifier);
final SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 443, socketFactory));

final PoolingClientConnectionManager cm = new PoolingClientConnectionManager(registry);
cm.setMaxTotal(100);
cm.setDefaultMaxPerRoute(50);
final HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(httpParams, timeout);

httpClient = new DefaultHttpClient(cm, httpParams);

((DefaultHttpClient) httpClient).setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse hr, HttpContext hc) {
return 0;
}
});
httpClient.getParams().setParameter("http.socket.timeout", 900000);

UPD2:修改了 SSLSocketFactory(“收到致命警报:bad_record_mac”问题)

  public class SSLv3SocketFactory extends SSLSocketFactory {

private final javax.net.ssl.SSLSocketFactory socketfactory;

public SSLv3SocketFactory(SSLContext sslContext, X509HostnameVerifier hostnameVerifier) {
super(sslContext, hostnameVerifier);
this.socketfactory = sslContext.getSocketFactory();
}

@Override
public Socket createLayeredSocket(
final Socket socket,
final String host,
final int port,
final boolean autoClose) throws IOException, UnknownHostException {
SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
socket,
host,
port,
autoClose);
sslSocket.setEnabledProtocols(new String[]{"SSLv3"});


return sslSocket;
}

@Override
public Socket connectSocket(
final Socket socket,
final InetSocketAddress remoteAddress,
final InetSocketAddress localAddress,
final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {

if (socket instanceof SSLSocket) {
((SSLSocket) socket).setEnabledProtocols(new String[]{"SSLv3"});;
}
return super.connectSocket(socket, remoteAddress, localAddress, params);
}
}

UPD3:问题只存在于 SSLv3,TLSv1 工作正常

最佳答案

HttpClient 仅在可以确保它们属于相同的用户/安全上下文(出于显而易见的原因)时才重新使用持久的 SSL 连接和客户端身份验证。

确保您对所有逻辑相关的请求使用相同的 HttpContext。这将确保安全主体(客户端证书的 DN)将在各个 HTTP 请求之间传播。

跟进

它调出服务器只是不想重新使用连接。每个响应都包含 'Connection: close' 指令,提示客户端在收到响应后关闭连接。但是,服务器可能会根据请求消息的组成以不同方式对待不同的客户端。尝试使用不同的 User-Agent header 值伪装 HttpClient,看看是否有任何不同。

关于java - HttpClient : ssl handshake on every request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17929191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com