Мне удалось включить правильный набор шифров, но в процессе я нарушил сравнение имени хоста.Получение несоответствия имени хоста после включения устаревшего набора шифров в Android 7 org.apache.http (Apache HttpClient 4.0)
Вот код, прежде чем я начал:
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 20000);
DefaultHttpClient client = new DefaultHttpClient(params);
HttpPost request = new HttpPost(url);
...
HttpResponse response = client.execute(request);
...
Начиная с Android 7, я получаю следующее сообщение об ошибке:
javax.net.ssl.SSLHandshakeException: Handshake failed
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:406)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:170)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:366)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
...
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x9f7a03c0: Failure in SSL library, usually a protocol error
error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/s3_pkt.c:610 0x9c571b00:0x00000001)
error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/s3_clnt.c:764 0x9c614196:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
... 19 more
Это, очевидно, связано с веб-сервера, требующего клиента в службу поддержки RC4, который, как представляется, поддерживается through Android 6 (api 23). К сожалению, обновление веб-сервера в настоящий момент невозможно, поэтому мне нужно включить требуемый набор шифров в приложении.
Вот что я пробовал:
// HttpParams params is same as before
DefaultHttpClient client = new DefaultHttpClient(params);
ClientConnectionManager connManager = client.getConnectionManager();
SchemeRegistry schemeRegistry = connManager.getSchemeRegistry();
Scheme scheme = schemeRegistry.getScheme("https");
final SSLSocketFactory impl = (SSLSocketFactory) scheme.getSocketFactory();
SocketFactory sf = new SocketFactory() {
@Override
public Socket createSocket() throws IOException {
SSLSocket socket = (SSLSocket) impl.createSocket();
ArrayList<String> list = new ArrayList<>(Arrays.asList(socket.getEnabledCipherSuites()));
list.add("SSL_RSA_WITH_RC4_128_SHA");
socket.setEnabledCipherSuites(list.toArray(new String[list.size()])); // this is where I add the required cipher suites after the SSLSocket is created
return socket;
}
// unchanged wrappers
@Override
public Socket connectSocket(Socket socket, String s, int i, InetAddress inetAddress, int i1, HttpParams httpParams) throws IOException { return impl.connectSocket(socket, s, i, inetAddress, i1, httpParams); }
@Override
public boolean isSecure(Socket socket) throws IllegalArgumentException { return impl.isSecure(socket); }
};
schemeRegistry.register(new Scheme("https", sf, 443));
// request & execute same as before
Это успешно добавляет необходимый набор шифров, но, кажется, разорвать сравнение имен хостов, потому что тогда я получаю следующее:
javax.net.ssl.SSLException: hostname in certificate didn't match: <10.10.10.10> != <sub.example.com> OR <sub.example.com>
IP-адрес является правильным для этот хозяин. Предположительно, все мои переопределения/обертки привели к тому, что вместо исходного https://sub.example.com/
имя хоста было использовано IP-адрес, прошедший в пределах url
.
Вы можете помочь мне здесь? Я не знаю, как преодолеть проблему с неправильным совпадением имени хоста.