Android okhttp3 Рукопожатие не удалось с причалом, используя https - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть приложение, в котором я делаю POST-запросы с помощью okhttp3 для отправки файлов и получения ответа.Бэкэнд использует Jetty, и он отлично работает, когда я делаю http-запросы.Но когда я пытаюсь изменить конфигурацию на https программно (вы можете увидеть это в прокомментированном блоке try), это не удается.Я получаю это исключение:

W/System.err: javax.net.ssl.SSLHandshakeException: Handshake failed
W/System.err:     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:434)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:302)
    at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:270)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:162)
    at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
    at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
    at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
    at okhttp3.RealCall.execute(RealCall.java:77)
    at app.com.myapp.myUploadService$UpdateTask.sendToBackend(UploadService.java:270)
    at app.com.myapp.myUploadService$UpdateTask.uploadFiles(UploadService.java:226)
W/System.err:     at app.com.myapp.myUploadService$UpdateTask.doInBackground(UploadService.java:133)
    at app.com.myapp.myUploadService$UpdateTask.doInBackground(UploadService.java:118)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
W/System.err: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x724d289a00: Failure in SSL library, usually a protocol error
error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/tls_record.c:522 0x724d2383a0:0x00000001)
error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/handshake_client.c:889 0x724b9318a6:0x00000000)
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
    ... 29 more

вот код бэкэнда:

org.eclipse.jetty.server.Server = server = new Server(8082);

// servlet handlers
ServletContextHandler servletContext =
        new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContext.setContextPath("/");

// jersey
ResourceConfig rConfig = new ResourceConfig();
rConfig.packages("com.mypackage.package");
ServletHolder jersey = new ServletHolder(new ServletContainer(rConfig));
servletContext.addServlet(jersey, "/*");

// IN THIS TRY BLOCK, I TRY TO CONFIGURE THE SERVER TO HTTPS. WITHOUT IT
// IT WORKS, BUT IS HTTP.
try {
    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());

    char[] password = "password".toCharArray();
    keystore.load(null, password);

    // Store away the keystore.
    FileOutputStream fos = new FileoutputStream("ks.keystore");
    keystore.store(fos, password);
    fos.close();

    SslContextFactory cf = new SslContextFactory();
    cf.setKeyStore(keystore);
    cf.setKeyStorePassword("password");

    HttpConfiguration config = new HttpConfiguration();
    config.addCustomizer(new SecureRequestCustomizer());
    config.setSecureScheme("https");
    config.setSecurePort(8082);

    HttpConfiguration sslConfiguration = new HttpConfiguration(config);
    sslConfiguration.addCustomizer(new SecureRequestCustomizer());
    ServerConnector sslConnector = new ServerConnector(server,
            new SslConnectionFactory(cf, HttpVersion.HTTP_1_1.toString()),
            new HttpConnectionFactory(sslConfiguration));
    sslConnector.setPort(8082);
    sslConnector.setName("secured");
    server.setConnectors(new Connector[]{sslConnector});
} catch (Exception e){
    logger.error(e.getMessage());
}

// add handlers to HandlerList
HandlerList handlers = new HandlerList();
handlers.addHandler(servletContext);

// add HanderList to server
server.setHandler(handlers);

И клиент (приложение для Android) делает это:

    Request request = new Request.Builder()
    .url(https://urltomyserver:8082)
    .post(requestBody)
    .build();

    // THE FOLLOWING LINE CAUSES THE EXCEPTION
    try (Response response = client.newCall(request).execute()) {
         //do stuff
    }...

Я простохотите использовать https, чтобы содержимое и параметры запроса URL были зашифрованы.Никаких ультра-модных вещей.Буду благодарен за любую помощь.

...