问题描述
我正在将Kuzzle与他的Android SDK(3.0.10)结合使用,以通过发布/订阅系统接收通知。
在Android 5和6中,当我尝试连接到服务器时,将执行错误回调,并显示以下消息:{“ message”:“ SSL握手异常中止:ssl = 0x7f382c540280:系统调用期间I / O错误,连接重置同行”}
在其他版本的Android中,它运行完美。
Options options = new Options();
options.setPort(443);
options.setofflineMode(Mode.AUTO);
options.setSsl(true);
kuzzle = new Kuzzle(kuzzleHost,options,new ResponseListener<Void>() {
@Override
public void onSuccess(Void response) {
initSubscriptions();
}
@Override
public void onError(JSONObject error) {
Log.e("Kuzzle","error");
}
});
} catch (Exception e) {
Utils.caughtException(KuzzleSub.class.getSimpleName(),e);
}
app / build.gradle依赖项
dependencies {
implementation 'io.kuzzle:sdk-android:3.0.10'
implementation 'tech.gusavila92:java-android-websocket-client:1.2.2'
调试Kuzzle和gusavila92.websocketclient.WebSocketClient类我发现在Android 5中,启用了websocket的协议是SSLv3,TLSv1,TLSv1.1,TLSv1.2。但是,在Android 7及更高版本中,未启用SSLv3。
在Internet上搜索时,我发现了多种解决方案,例如禁用SSLv3,仅启用TLSv1.2,创建新的SSLFactory。下面的代码是我尝试使用另一个SSLFactory创建扩展Kuzzle.java和SSLFactory.java
的类public class ExtendedKuzzle extends Kuzzle {
public ExtendedKuzzle(@NonNull String host,Options options,ResponseListener<Void> connectionCallback) throws URISyntaxException {
super(host,connectionCallback);
}
public ExtendedKuzzle(@NonNull String host) throws URISyntaxException {
super(host);
}
public ExtendedKuzzle(@NonNull String host,ResponseListener<Void> cb) throws URISyntaxException {
super(host,cb);
}
public ExtendedKuzzle(@NonNull String host,Options options) throws URISyntaxException {
super(host,options);
}
@Override
protected WebSocketClient createSocket() throws URISyntaxException {
WebSocketClient webSocketClient = super.createSocket();
try {
// SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
// sslContext.init(null,null,null);
webSocketClient.setSSLSocketFactory(new TLSSocketFactory());
} catch (Exception e) {
e.printstacktrace();
}
return webSocketClient;
}
}
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() throws KeyManagementException,NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null,null);
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s,String host,int port,boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s,host,port,autoClose));
}
@Override
public Socket createSocket(String host,int port) throws IOException,UnkNownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host,port));
}
@Override
public Socket createSocket(String host,InetAddress localHost,int localPort) throws IOException,localHost,localPort));
}
@Override
public Socket createSocket(InetAddress host,int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host,port));
}
@Override
public Socket createSocket(InetAddress address,InetAddress localAddress,int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address,localAddress,localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
// List<String> enabledProtocols = new ArrayList<>(Arrays.asList(((SSLSocket)socket).getEnabledProtocols()));
// if (enabledProtocols.size() > 1) {
// enabledProtocols.remove("SSLv3");
// ((SSLSocket)socket).setEnabledProtocols(enabledProtocols.toArray(new String[0]));
// }
}
return socket;
}
}
我也试图设置一个“无疑问”的TrustManager,但没有成功:
public static SSLSocketFactory createSslSocketFactory() throws Exception {
TrustManager[] byPasstrustManagers = new TrustManager[] { new x509trustmanager() {
public X509Certificate[] getAcceptedissuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] chain,String authType) {
}
public void checkServerTrusted(X509Certificate[] chain,String authType) {
}
} };
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null,byPasstrustManagers,new java.security.SecureRandom());
return sslContext.getSocketFactory();
}
如果有人知道发生了什么,我将非常感激。非常感谢!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)