Java SSLSocket/ServerSocket: 在 Android 上强制使用 TLSv1.2 时握手失败

huangapple 未分类评论51阅读模式
英文:

Java SSLSocket/ServerSocket: Handshake failed when forcing TLSv1.2 on Android

问题

基本上,我正在使用SSLSocket从Android设备连接到SSLServerSocket以传输应用程序数据。我从LetsEncrypt获得了一个证书,并将fullchain.pem与privkey.pem组合在一起,以便能够按照此教程进行JKS转换。

经过一些尝试,我遇到了这个异常,我无法修复:

Android日志:

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握手中止:ssl=0x738d61bfc8:SSL库中的失败,通常是协议错误
    error:10000412:ssl例程: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:握手失败
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)
...

服务器日志:

javax.net.ssl.SSLHandshakeException:空服务器证书链
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    ...
    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;
}
// 握手操作

服务器代码:

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);

// 接受客户端连接

注意:此处的翻译可能不会在所有上下文中都适用,因为它是从英文文本中生成的。如果有特定的技术术语或语境,您可能需要进行进一步的调整。

<details>
<summary>英文:</summary>

Basically I am using SSLSocket to connect from an Android device to a SSLServerSocket for transmitting application data. I got myself a cert from LetsEncrypt and combined fullchain.pem with privkey.pem to be able to follow [this][1] tutorial on how to convert to JKS.

After some tinkering I came across this Exception which I am not able to fix:

Android Log:

    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

Server Log:

    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)


Client Code:

        SSLContext context = null;
        try {
            context = SSLContext.getInstance(&quot;TLSv1.2&quot;);
            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

Server Code:

            KeyStore ks = KeyStore.getInstance(&quot;JKS&quot;);
            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(&quot;TLSv1.2&quot;);
            context.init(kmf.getKeyManagers(),null,null);
            SSLServerSocketFactory factory = context.getServerSocketFactory();

            socket = (SSLServerSocket) factory.createServerSocket(address.getPort());
            socket.setNeedClientAuth(true);
            socket.setUseClientMode(false);
           
            //accept clients


  [1]: https://docs.oracle.com/cd/E35976_01/server.740/es_admin/src/tadm_ssl_convert_pem_to_jks.html

</details>


huangapple
  • 本文由 发表于 2020年7月24日 23:42:06
  • 转载请务必保留本文链接:https://java.coder-hub.com/63076918.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定