gpt4 book ai didi

java - Android 6 及更高版本中的 Android SSLSocket 握手失败

转载 作者:搜寻专家 更新时间:2023-10-30 20:53:39 25 4
gpt4 key购买 nike

我编写了一个基于 Java SSLServerSocket 的服务器,它接受连接并通过自定义二进制协议(protocol)与 android 应用程序通信:

ServerSocket serverSocket = SSLServerSocketFactory.getDefault().createServerSocket(1234);
while (true) {
Socket socket = serverSocket.accept();
...
}

我使用以下参数运行服务器:

-Djavax.net.ssl.keyStore=keystore.jks
-Djavax.net.ssl.keyStorePassword=<PASSWORD>

证书是使用以下构建公钥和私钥集的教程生成的:http://judebert.com/progress/archives/425-Using-SSL-in-Java,-Part-2.html :

keytool -genkeypair -keystore keystore.jks -alias keyname
keytool -export -alias keyname -file keyname.crt -keystore keystore.jks
keytool -importcert -file keyname.crt -keystore truststore.jks

此外,我通过使用 bouncycaSTLe 构建信任库使其与 android 兼容:

keytool -importkeystore -srckeystore truststore.jks -srcstoretype JKS -srcstorepass <PASSWORD> -destkeystore truststore.bks -deststoretype BKS -deststorepass <PASSWORD> -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-ext-jdk15on-1.58.jar

在此处下载 bouncycaSTLe 提供程序:https://www.bouncycastle.org/latest_releases.html

并将生成的 truststore.bks 移动到原始资源文件夹中。

在 Android 上,我使用以下代码构建一个 SSLSocketFactory,它允许我导入生成的 bouncycaSTLe 证书,该证书对服务器进行身份验证:

KeyStore trustStore = KeyStore.getInstance("BKS");
InputStream trustStoreStream = context.getResources().openRawResource(R.raw.truststore);
trustStore.load(trustStoreStream, "<PASSWORD>".toCharArray());

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

Socket socket = sslContext.getSocketFactory().createSocket("ip", 1234);
... use socket

这适用于 6 以下的 Android 版本。我的问题是在版本 6 和更高版本中,我在尝试使用套接字时遇到异常:

 Shutting down connection Socket[address=/ip,port=1234,localPort=321321] due to exception Handshake failed
javax.net.ssl.SSLHandshakeException: Handshake failed
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
at com.example.Client.connect(Client.java:97)
at com.example.Client.start(Client.java:60)
at com.example.BackendServiceFactory$2.call(BackendServiceFactory.java:136)
at com.example.BackendServiceFactory$2.call(BackendServiceFactory.java:130)
...
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xe69ec900: Failure in SSL library, usually a protocol error
error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/s3_pkt.c:641 0xe2d10880:0x00000001)
error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/s3_clnt.c:800 0xe6ea5af3:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
... 24 more

我不确定这里发生了什么。在处理客户端证书的过程中似乎出现了失误,这可能是密码套件不匹配吗?

我已经将一个包含 Java 服务器、Java 客户端和 Android 客户端的最小示例放在一起来帮助诊断这里的问题:

https://github.com/johncarl81/androidCA

最佳答案

我认为这将是一个简单的修复。似乎我需要在第一个 keytool 命令中指定 key 算法:

keytool -genkeypair -keystore keystore.jks -alias keyname -keyalg RSA

这会生成一个 2048 位的 RSA key ,它与 android < 6 和 >= 6 的版本兼容。

关于java - Android 6 及更高版本中的 Android SSLSocket 握手失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46375111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com