我将Nexus 5X(API级别27)用作React Native应用的仿真器。我正在尝试使用SSLSockets将其连接到我的Java服务器,但是在连接它后立即出现错误:握手失败
SSL handshake aborted: ssl=0x9613a1c0: Failure in SSL library, usually a protocol error
error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/tls_record.cc:579 0x9679afc0:0x00000001)
error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/handshake_client.cc:893 0xa43b3dc3:0x00000000)
invoke JavaMethodWrapper.java:383
invoke JavaModuleWrapper.java:160
run NativeRunnable.java
handleCallback Handler.java:790
dispatchMessage Handler.java:99
dispatchMessage MessageQueueThreadHandler.java:29
loop Looper.java:164
run MessageQueueThreadImpl.java:192
run Thread.java:764*
有一段时间,由于错误消息,我认为它正在使用SSLv3,但是在Wireshark中检查了连接之后,我注意到它实际上是TLSv1.2。然后,我尝试为服务器和android客户端强制实施特定的密码套件,而没有运气。编写自定义SocketFactory类也无济于事。
我发现了另一个可能与我的问题有关的问题:SSLHandshakeException: Handshake failed on Android N/7.0。我仍然相当有信心,我的问题与受支持的密码套件和/或椭圆曲线密码学有关。
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket connection = (SSLSocket) factory.createSocket("127.0.0.1", 4192);
connection.setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"});
connection.setUseClientMode(true);
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
DataInputStream input = new DataInputStream(connection.getInputStream());
String[] cipher_suites = connection.getSupportedCipherSuites();
connection.setEnabledCipherSuites(cipher_suites);
connection.startHandshake();
SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket server = (SSLServerSocket) factory.createServerSocket(4192, 1);
SSLSocket connection = (SSLSocket) server.accept();
DataInputStream input = new DataInputStream(connection.getInputStream());
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
connection.setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"});
String[] cipher_suites = connection.getSupportedCipherSuites();
connection.setEnabledCipherSuites(cipher_suites);
connection.startHandshake();
服务器本身可以正常工作,并且可以使用完全相同的代码从另一台计算机连接。它在openjdk 10.0.1上运行。与android相同的版本。有趣的是,它在发行说明中说:
security-libs / javax.net.ssl 3DES密码套房残疾人 为了提高SSL / TLS连接的强度,已通过jdk.tls.disabledAlgorithms安全属性在JDK的SSL / TLS连接中禁用了3DES密码套件。
模拟器中的android版本是8.1,我也在物理设备上用7.0测试了它。错误消息都是一样的。有人遇到过这个问题吗?
这些是我随客户端Hello收到的密码套件和已确认的TLS版本
Version: TLS 1.2 (0x0303)
Cipher Suites (14 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
接着是握手失败警报:
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.2 (0x0303)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)
答案 0 :(得分:1)
我终于开始工作了。问题是我用错误的算法创建了密钥库文件。我使用keytool通过-keyalg RSA
创建了一个新商店,现在我的服务器可以在客户端上使用通用RSA密码了。