В соответствии с документами в Android для SSLSocket
и SSLContext
, протоколы TLS v1.1 и v1.2 поддерживаются в уровне API 16+, но по умолчанию не включены.
http://developer.android.com/reference/javax/net/ssl/SSLSocket.html
http://developer.android.com/reference/javax/net/ssl/SSLContext.html
Как включить его на устройстве под управлением Android 4.1 или новее (но ниже 5.0)?
Я попытался создать настраиваемый SSLSocketFactory, который включает все поддерживаемые протоколы при создании Socket
, а затем использовать мою собственную реализацию как:
HttpsURLConnection.setDefaultSSLSocketFactory(новый MySSLSocketFactory());
public class MySSLSocketFactory extends SSLSocketFactory {
private SSLContext sc;
private SSLSocketFactory ssf;
public MySSLSocketFactory() {
try {
sc = SSLContext.getInstance("TLS");
sc.init(null, null, null);
ssf = sc.getSocketFactory();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose)
throws IOException {
SSLSocket ss = (SSLSocket) ssf.createSocket(s, host, port, autoClose);
ss.setEnabledProtocols(ss.getSupportedProtocols());
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
return ss;
}
@Override
public String[] getDefaultCipherSuites() {
return ssf.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return ssf.getSupportedCipherSuites();
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
SSLSocket ss = (SSLSocket) ssf.createSocket(host, port);
ss.setEnabledProtocols(ss.getSupportedProtocols());
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
return ss;
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
SSLSocket ss = (SSLSocket) ssf.createSocket(host, port);
ss.setEnabledProtocols(ss.getSupportedProtocols());
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
return ss;
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException, UnknownHostException {
SSLSocket ss = (SSLSocket) ssf.createSocket(host, port, localHost, localPort);
ss.setEnabledProtocols(ss.getSupportedProtocols());
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
return ss;
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
int localPort) throws IOException {
SSLSocket ss = (SSLSocket) ssf.createSocket(address, port, localAddress, localPort);
ss.setEnabledProtocols(ss.getSupportedProtocols());
ss.setEnabledCipherSuites(ss.getSupportedCipherSuites());
return ss;
}
}
Но он по-прежнему дает исключение при попытке установить соединение с сервером, на котором включен Только TLS 1.2.
Вот исключение, которое я получаю:
03-09 09: 21: 38.427: W/System.err(2496): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL-квитирование отменено: ssl = 0xb7fa0620: Ошибка в библиотеке SSL, обычно ошибка протокола
03-09 09: 21: 38.427: W/System.err(2496): ошибка: 14077410: SSL подпрограмм: SSL23_GET_SERVER_HELLO: отказ при сбое вызова sslv3 (внешний/openssl/ssl/s23_clnt.c: 741 0xa90e6990: 0x00000000)