我有一个应用程序,其中使用okhttp3发出POST请求以发送文件并获得答案。后端使用码头,并且在我发出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查询参数进行加密。没有超级花哨的东西。 感谢您的帮助。