java - Java SSLSocket/ServerSocket:在 Android 上强制 TLSv1.2 时握手失败
问题描述
基本上,我使用 SSLSocket 从 Android 设备连接到 SSLServerSocket 以传输应用程序数据。我从 LetsEncrypt 获得了一个证书,并将 fullchain.pem 与 privkey.pem 结合起来,以便能够按照本教程了解如何转换为 JKS。
经过一些修补后,我遇到了这个我无法修复的异常:
安卓日志:
2020-07-24 17:10:00.807 2440-2512/at.ls.bikewithme I/System.out: [TLSv1, TLSv1.1, TLSv1.2, TLSv1.3]
2020-07-24 17:10:01.132 2440-2512/at.ls.bikewithme V/NativeCrypto: SSL handshake aborted: ssl=0x738d61bfc8: Failure in SSL library, usually a protocol error
error:10000412:SSL routines:OPENSSL_internal:SSLV3_ALERT_BAD_CERTIFICATE (third_party/openssl/boringssl/src/ssl/tls_record.cc:592 0x738d656088:0x00000001)
2020-07-24 17:10:01.136 2440-2512/at.ls.bikewithme W/System.err: javax.net.ssl.SSLHandshakeException: Handshake failed
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms@202414019@20.24.14 (040400-319035315):35)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.run(SecureClient.java:129)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.retryConnection(SecureClient.java:151)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.run(SecureClient.java:80)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.retryConnection(SecureClient.java:151)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.run(SecureClient.java:80)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.retryConnection(SecureClient.java:151)
2020-07-24 17:10:01.137 2440-2512/at.ls.bikewithme W/System.err: at me.ls.client.SecureClient.run(SecureClient.java:80)
2020-07-24 17:10:01.138 2440-2512/at.ls.bikewithme W/System.err: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x738d61bfc8: Failure in SSL library, usually a protocol error
2020-07-24 17:10:01.138 2440-2512/at.ls.bikewithme W/System.err: error:10000412:SSL routines:OPENSSL_internal:SSLV3_ALERT_BAD_CERTIFICATE (third_party/openssl/boringssl/src/ssl/tls_record.cc:592 0x738d656088:0x00000001)
2020-07-24 17:10:01.138 2440-2512/at.ls.bikewithme W/System.err: at com.google.android.gms.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
2020-07-24 17:10:01.138 2440-2512/at.ls.bikewithme W/System.err: at com.google.android.gms.org.conscrypt.NativeSsl.doHandshake(:com.google.android.gms@202414019@20.24.14 (040400-319035315):6)
2020-07-24 17:10:01.138 2440-2512/at.ls.bikewithme W/System.err: at com.google.android.gms.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(:com.google.android.gms@202414019@20.24.14 (040400-319035315):16)
2020-07-24 17:10:01.138 2440-2512/at.ls.bikewithme W/System.err: ... 7 more
服务器日志:
javax.net.ssl.SSLHandshakeException: Empty server certificate chain
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:258)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:381)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:366)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:167)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1462)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1370)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:437)
at me.ls.server.SecureServer.run(SecureServer.java:89)
客户代码:
SSLContext context = null;
try {
context = SSLContext.getInstance("TLSv1.2");
context.init(null,null,null);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
if(context == null) return;
SSLSocketFactory factory = context.getSocketFactory();
try {
socket = (SSLSocket) factory.createSocket(address.getHostString(), address.getPort());
System.out.println(Arrays.toString(socket.getSupportedProtocols()));
socket.setUseClientMode(true);
} catch (IOException ioException) {
if (running) {
retryConnection(2000);
}
return;
}
//Handshake
服务器代码:
KeyStore ks = KeyStore.getInstance("JKS");
InputStream ksIs = new FileInputStream(keystoreFile);
try {
ks.load(ksIs, keystorePass.toCharArray());
} finally {
ksIs.close();
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
kmf.init(ks, keystorePass.toCharArray());
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(),null,null);
SSLServerSocketFactory factory = context.getServerSocketFactory();
socket = (SSLServerSocket) factory.createServerSocket(address.getPort());
socket.setNeedClientAuth(true);
socket.setUseClientMode(false);
//accept clients
解决方案
推荐阅读
- angular - 自定义复选框背景图像未出现-Angular 5部署后的Bootstrap 4
- python - Python 问题:TypeError: unhashable type: 'slice' during web scraping
- android - 进度对话框永远不会出现
- c# - 如何使用滑块从其生成器对象中的生成对象更改属性
- ruby-on-rails - 尝试使用邮递员登录时出现Rails路由错误
- javascript - 在Javascript函数中添加多种样式不起作用
- android - 如何在 android 上运行 python 脚本?
- ios - How to fix iOS orientation with new API willAnimateRotationToInterfaceOrientation
- python - 如何从python中的布尔逻辑表达式中提取变量
- java - Java中2个坐标之间的距离