的Android棒棒糖预设备给错误“SSL握手中止:SSL = 0x618d9c18:系统调用,通过对等连接复位期间I/O错误”
荫有这个奇怪的问题,其中改造不断抛出我的Android棒棒糖预设备给错误“SSL握手中止:SSL = 0x618d9c18:系统调用,通过对等连接复位期间I/O错误”
在奇巧“SSL握手中止:SSL = 0x618d9c18:系统调用,由对等 连接复位期间I/O错误”
,而相同的代码在棒棒糖设备工作正常。 IAM使用OkHttpClient客户像下面
public OkHttpClient getUnsafeOkHttpClient() {
try {
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
int cacheSize = 10 * 1024 * 1024; // 10 MB
Cache cache = new Cache(getCacheDir(), cacheSize);
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
final SSLSocketFactory sslSocketFactory = sslContext
.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient = okHttpClient.newBuilder()
.cache(cache)
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
荫使用该客户端在改造这样
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.client(getUnsafeOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
编辑:添加getUnsafeOkHttpClient()在这里有没有影响
FYI:发行固定后这个崩溃被修复了Caused by: java.lang.IllegalStateException: Unable to extract the trust manager on [email protected], sslSocketFactory is class navneet.com.devinered.service.TLSSocketFactory
终于找到了解决这个问题,它不是一个完整的解决方案是通过Jesse Wilson从okhttp,方here提到的黑客攻击。正如我所说,这是一个简单的黑客,我不得不对我SSLSocketFactory的变量重命名为
private SSLSocketFactory delegate;
通知,如果你给比委托其他任何名称,将抛出错误。荫张贴我下面
完整的解决方案这是我TLSSocketFactory
类public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
delegate = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(delegate.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
,这是我如何与okhttp用它和改造
OkHttpClient client=new OkHttpClient();
try {
client = new OkHttpClient.Builder()
.sslSocketFactory(new TLSSocketFactory())
.build();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
我在这里获得了api.data.gov.in的SSL/TLS信息 - https://www.ssllabs.com/ssltest/analyze.html?d=api.data.gov.in
它看起来像只支持TLSv1.2。旧的Android版本确实与最新的TLS版本有关。在ssllabs页面的“Handshake Simulation”一节中,您甚至可以看到您的问题。
有关可用解决方案,请参阅How to enable TLS 1.2 support in an Android application (running on Android 4.1 JB)。
它没有为我工作,它现在崩溃与'引起:java.lang.IllegalStateException:无法提取信任管理器[email protected],sslSocketFactory是类navneet.com.devinered.service.TLSSocketFactory ' –
你有使用TLSv1.2工作?如果您使用默认值,会怎么样? – algrid
@algrid没有任何影响,如果我更改ssl实例,所以我删除了整个不安全的客户端改造,仍然只适用于棒棒糖,而不是kitkat –
你的服务器端有什么?也许你可以从你的服务器上获取一些日志? – algrid