一段时间后返回 Android。我刚刚购买了 EV 证书,并尝试使用 SSL/TSL 连接到我的 Web 服务。我得到:
2021-07-23 09:52:12.009 26190-26225/xx.xx.wb5000dispenser E/xx.xx.wb5000dispenser.service.DispenseServiceImpl: Error registering site
javax.net.ssl.SSLHandshakeException: Handshake failed
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:286)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:192)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:299)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:237)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:472)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:26)
at xx.xx.wb5000dispenser.service.DispenseServiceImpl.callPost(DispenseServiceImpl.java:72)
at xx.xx.wb5000dispenser.service.DispenseServiceImpl.registerSite(DispenseServiceImpl.java:50)
at xx.xx.wb5000dispenser.service.Wb5000Service$DailyRegisterThread.run(Wb5000Service.java:57)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x9fa470c8: Failure in SSL library, usually a protocol error
error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER (external/boringssl/src/ssl/tls_record.cc:242 0x9d1e6f1b:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:375)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:224)
... 16 more
我在此处的其中一个答案中发现我应该尝试 testssl.sh。我安装了它,这是一些报告...
...
Testing protocols via sockets except NPN+ALPN
SSLv2 not offered (OK)
SSLv3 not offered (OK)
TLS 1 not offered
TLS 1.1 not offered
TLS 1.2 offered (OK)
TLS 1.3 offered (OK): final
NPN/SPDY http/1.1 (advertised)
ALPN/HTTP2 http/1.1 (offered)
...
Rating (experimental)
Rating specs (not complete) SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)
Specification documentation https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide
Protocol Support (weighted) 100 (30)
Key Exchange (weighted) 90 (27)
Cipher Strength (weighted) 90 (36)
Final Score 93
Overall Grade A
Grade cap reasons Grade capped to A. HSTS is not offered
让我知道查看更多内容是否有用...
我查看了服务器(在 AWS 上托管的 nginx),在此期间日志中没有错误。
这里是 SSL 上下文的创建:
try {
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException ex) {
Log.e(TAG, "Error creating SSL context", ex);
}
TSLv1.3 因不受支持而失败。
这是我的连接代码:
try {
URL url = new URL(urlName);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.setDoOutput(true);
urlConnection.setFixedLengthStreamingMode(bytesToSend.length);
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); //Exception here
out.write(bytesToSend);
out.flush();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
result = readStreamAsString(in);
}
catch(Exception exception) {
Log.e(TAG, "Error registering site", exception);
throw new Square1Exception("Error hitting:" + urlName, exception);
}
如输出流创建所示那样爆炸。
我的平板电脑运行的是 Android 9,这比我发现的大多数类似问题都要新。
感谢所有建议。
答案 0 :(得分:0)
正如 Joy 和 alexrait 所建议的,问题不在于指定 SSL 上下文。显然,默认情况下,android 不会尝试最好的。 :(
所以,我在这里添加了代码:
try {
sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException | KeyManagementException ex) {
Log.e(TAG, "Error creating SSL context", ex);
}
然后添加这一行来使用它:
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
现在似乎一切正常。感谢您的帮助。