Désactiver SSL en tant que protocole dans HttpsURLConnection

En raison de la CANICHE de la vulnérabilité, de mon serveur, hébergé dans Amazon AWS ne plus soutenir SSLv3.

En conséquence, la première connexion HTTPS mon application Android ne contre le serveur provoque une erreur lors de la connexion a été établie.

Error reading server response: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x77d8ab68: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x7339ad74:0x00000000)
       [....]
Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x77d8ab68: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x7339ad74:0x00000000)
       at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:448)
       at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)
       at com.android.okhttp.Connection.connect(Connection.java:107)
       at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
       at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
       at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)

L'erreur ne se produit que dans la première demande. Les demandes ultérieures de travail pour un certain temps.

Pour résoudre ce problème que je suis en train de supprimer SSL à partir de la liste des protocoles acceptés par le client Android, et s'assurer que je vais seulement avec le protocole TLS.
Pour ce faire, j'ai mis une coutume SSLSocketFactory qui supprime SSL à partir de la liste des protocoles activés et pris en charge monogramme suites.

/**
* SSLSocketFactory that wraps one existing SSLSocketFactory and delegetes into it adding
* a new cipher suite
*/
public class TLSOnlySocketFactory extends SSLSocketFactory {
private final SSLSocketFactory delegate;
public TLSOnlySocketFactory(SSLSocketFactory delegate) {
this.delegate = delegate;
}
@Override
public String[] getDefaultCipherSuites() {
return getPreferredDefaultCipherSuites(this.delegate);
}
@Override
public String[] getSupportedCipherSuites() {
return getPreferredSupportedCipherSuites(this.delegate);
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
final Socket socket = this.delegate.createSocket(s, host, port, autoClose);
((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
((SSLSocket)socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));
return socket;
}
[.....]
((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
((SSLSocket) socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));
return socket;
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
final Socket socket = this.delegate.createSocket(host, port);
((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
((SSLSocket) socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));
return socket;
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
final Socket socket = this.delegate.createSocket(address, port, localAddress, localPort);
((SSLSocket)socket).setEnabledCipherSuites(getPreferredDefaultCipherSuites(delegate));
((SSLSocket) socket).setEnabledProtocols(getEnabledProtocols((SSLSocket)socket));
return socket;
}
private String[] getPreferredDefaultCipherSuites(SSLSocketFactory sslSocketFactory) {
return getCipherSuites(sslSocketFactory.getDefaultCipherSuites());
}
private String[] getPreferredSupportedCipherSuites(SSLSocketFactory sslSocketFactory) {
return getCipherSuites(sslSocketFactory.getSupportedCipherSuites());
}
private String[] getCipherSuites(String[] cipherSuites) {
final ArrayList<String> suitesList = new ArrayList<String>(Arrays.asList(cipherSuites));
final Iterator<String> iterator = suitesList.iterator();
while (iterator.hasNext()) {
final String cipherSuite = iterator.next();
if (cipherSuite.contains("SSL")) {
iterator.remove();
}
}
return suitesList.toArray(new String[suitesList.size()]);
}
private String[] getEnabledProtocols(SSLSocket socket) {
final ArrayList<String> protocolList = new ArrayList<String>(Arrays.asList(socket.getSupportedProtocols()));
final Iterator<String> iterator = protocolList.iterator();
while (iterator.hasNext()) {
final String protocl = iterator.next();
if (protocl.contains("SSL")) {
iterator.remove();
}
}
return protocolList.toArray(new String[protocolList.size()]);
}
}

Comme vous le voyez, mon SSLSocketFactory délégués dans un autre SSLSocketFactory et ce qu'il fait est tout simplement la suppression SSL à partir de la liste des protocoles activés.

- Je mettre en place cette usine

final TLSOnlySocketFactory tlsOnlySocketFactory = new TLSOnlySocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
HttpsURLConnection.setDefaultSSLSocketFactory(tlsOnlySocketFactory);

Cela ne résout PAS le problème. De temps à autre, je vois toujours l'erreur lors de la connexion a été établie. Curieusement, cela ne veut pas le réparer, mais il est clair que de minimiser les occurrences de la question.

Comment pourrais-je la force de la HttpsUrlConnection dans mon client Android pour utiliser uniquement TLS?

Merci.

source d'informationauteur GaRRaPeTa