jdk1.7.0_79和okhttp 3.8调用https url失败
main, WRITE: TLSv1 Handshake, length = 148
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, called close()
main, called closeInternal(true)
写和读TLSv1为什么仍然是handshake_failure,如果使用jdk8没问题,握手信息如下
main, WRITE: TLSv1.2 Handshake, length = 170
main, READ: TLSv1.2 Handshake, length = 93
main, READ: TLSv1.2 Handshake, length = 5516
客户端和服务器都使用TLSv1.2
因此尝试在此doc中按照以下方法将jdk7默认tls更改为TLSv1.2
// Enable TLS 1.0, 1.1 and 1.2 in an SSLSocket object.
sslSocket.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});
但是这次的调试信息仍然是handshake_failure
main, WRITE: TLSv1.2 Handshake, length = 178
main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, called close()
main, called closeInternal(true)
这次write使用TLSv1.2,但recv仍然使用TLSv1。为甚麽呢?如何让客户端和服务器端都使用TLSV1.2?
发布于 2020-12-31 18:41:42
OkHttp 3.12.12 (JDK7的3.x维护版本)应该已经在JDK7上激活了TLSv1.2。不知道为什么你自己会有这段代码。
public SSLContext getSSLContext() {
String jvmVersion = System.getProperty("java.specification.version");
if ("1.7".equals(jvmVersion)) {
try {
// JDK 1.7 (public version) only support > TLSv1 with named protocols
return SSLContext.getInstance("TLSv1.2");
} catch (NoSuchAlgorithmException e) {
// fallback to TLS
}
}
try {
return SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("No TLS provider", e);
}
}
您可以使用类似于https://github.com/square/okhttp/blob/master/okhttp-testing-support/src/main/kotlin/okhttp3/OkHttpDebugLogging.kt的代码启用帧日志记录
发布于 2021-07-23 19:33:55
正如另一个答案所指出的,如果使用Java 7
,您至少需要OkHttp 3.12.12来支持TLSv1.2。
但您还必须考虑到服务器中启用的密码套件必须与OkHttp兼容。
默认情况下,OkHttp使用17个“批准的”密码套件列表,您可以在https://github.com/square/okhttp/blob/okhttp_3.12.x/okhttp/src/main/java/okhttp3/ConnectionSpec.java (请参阅APPROVED_CIPHER_SUITES
)中查看这些套件。
但在这17个中,只有5个被de JDK 1.7支持:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
因此,如果服务器不接受此密码套件中的任何一个,您就会得到握手失败错误。
如果服务器接受Java7支持的一些密码套件,但这些密码套件不在OkHttp中的APPROVED_CIPHER_SUITES
列表中,那么您可以创建自己的ConnectionSpec
并在OkHttpClient.Builder
中使用它。例如,假设服务器接受Java 7支持的以下密码套件:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
您可以这样做,将它们添加到OkHttp支持的密码套件列表中:
// Create a list of cipher suites based on the default approved list by OkHttp
List<CipherSuite> cipherSuites = new ArrayList<CipherSuite>(ConnectionSpec.MODERN_TLS.cipherSuites());
// Add another cipher suites suported by Java 7
cipherSuites.add(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
cipherSuites.add(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256);
// Build a connection spec based on the default overridding the cipher suites.
ConnectionSpec COMPATIBLE_SPEC = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(cipherSuites.toArray(new CipherSuite[0]))
.build();
// Build a client specifying our own connection spec
OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Util.immutableList(COMPATIBLE_SPEC))
.build();
https://stackoverflow.com/questions/65515668
复制相似问题