客户端完成握手消息后的 SSL 握手错误
SSL Handshake error after Client Finished handshake message
我正在尝试对 server.com 执行双向 TLS 身份验证(已更改),并且我得到 Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking
、javax.net.ssl.SSLException: readHandshakeRecord
在 Produced client 完成握手消息之后。
我正在使用 AdoptOpenJDK 11.0.11.9-hotspot。
JVM 选项:
-Djavax.net.ssl.trustStore=cacerts
-Djavax.net.ssl.trustStoreType=PKCS12
-Djavax.net.ssl.trustStorePassword=changeit
-Djavax.net.ssl.keyStore=keystore
-Djavax.net.ssl.keyStoreType=PKCS12
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.debug=SSL,handshake
-Djdk.tls.client.protocols=TLSv1.3
-Djdk.tls.server.protocols=TLSv1.3
-Dhttps.protocols=TLSv1.3
我用来调试这个问题的代码:
public static void main (String[] args) throws IOException {
URL url = new URL( "https://server.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
con.connect();
}
成功执行握手步骤的日志:
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.505 MSK|ClientHello.java:653|Produced ClientHello handshake message ("ClientHello": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.505 MSK|ServerHello.java:872|Consuming ServerHello handshake message ("ServerHello": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.505 MSK|ServerHello.java:968|Negotiated protocol version: TLSv1.3
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.536 MSK|ChangeCipherSpec.java:246|Consuming ChangeCipherSpec message
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.552 MSK|EncryptedExtensions.java:171|Consuming EncryptedExtensions handshake message (<...>)
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.552 MSK|CertificateRequest.java:926|Consuming CertificateRequest handshake message ("CertificateRequest": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.568 MSK|CertificateMessage.java:1171|Consuming server Certificate handshake message ("Certificate": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.677 MSK|CertificateVerify.java:1161|Consuming CertificateVerify handshake message ("CertificateVerify": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.677 MSK|Finished.java:898|Consuming server Finished handshake message ("Finished": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.693 MSK|CertificateMessage.java:1139|Produced client Certificate message ("Certificate": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.724 MSK|CertificateVerify.java:1126|Produced client CertificateVerify handshake message ("CertificateVerify": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.739 MSK|Finished.java:673|Produced client Finished handshake message ("Finished": { <...> })
在那之后我得到:
javax.net.ssl|ERROR|01|main|2022-01-12 11:38:54.523 MSK|TransportContext.java:341|Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking (
"throwable" : {
javax.net.ssl.SSLException: readHandshakeRecord
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1335)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
at SbbidIntegraionApplication.main(SbbidIntegraionApplication.java:17)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:251)
at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.onProduceFinished(Finished.java:679)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.produce(Finished.java:658)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.onConsumeFinished(Finished.java:1011)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.consume(Finished.java:874)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
... 6 more}
)
javax.net.ssl|WARNING|01|main|2022-01-12 11:38:54.523 MSK|TransportContext.java:383|Fatal: failed to send fatal alert HANDSHAKE_FAILURE (
"throwable" : {
java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:380)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
at SbbidIntegraionApplication.main(SbbidIntegraionApplication.java:17)}
)
javax.net.ssl|DEBUG|01|main|2022-01-12 11:38:54.523 MSK|SSLSocketImpl.java:1638|close the underlying socket
javax.net.ssl|DEBUG|01|main|2022-01-12 11:38:54.523 MSK|SSLSocketImpl.java:1657|close the SSL connection (initiative)
Exception in thread "main" javax.net.ssl.SSLException: readHandshakeRecord
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1335)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
at SbbidIntegraionApplication.main(SbbidIntegraionApplication.java:17)
Suppressed: java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:380)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
... 5 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:251)
at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.onProduceFinished(Finished.java:679)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.produce(Finished.java:658)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.onConsumeFinished(Finished.java:1011)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.consume(Finished.java:874)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
... 6 more
Process finished with exit code 1
使用 curl 或 openssl 发送的相同请求已成功处理,我从服务器得到了预期的答复。
几乎在握手过程结束时出现这样的错误的原因是什么?
谢谢
更新:
在@dkotenko 发表评论后,我以编程方式初始化了 SSLContext:
public static void main (String []args) throws IOException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("keystore"), "changeit".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "changeit".toCharArray());
KeyStore trustStore = KeyStore.getInstance("PKCS12");
trustStore.load(new FileInputStream("cacerts"), "changeit".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL("server.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
}
但得到了完全相同的输出。
已解决。问题是密钥库中没有 CA 证书。
服务器管理员说在 server.com 联系负载平衡器时会检查客户端证书链中是否有特定 root CA 的证书 .
导入keystore后,整个握手过程就完成了,收到了服务器的正确响应
希望有一天这会对某人有所帮助:)
我正在尝试对 server.com 执行双向 TLS 身份验证(已更改),并且我得到 Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking
、javax.net.ssl.SSLException: readHandshakeRecord
在 Produced client 完成握手消息之后。
我正在使用 AdoptOpenJDK 11.0.11.9-hotspot。
JVM 选项:
-Djavax.net.ssl.trustStore=cacerts
-Djavax.net.ssl.trustStoreType=PKCS12
-Djavax.net.ssl.trustStorePassword=changeit
-Djavax.net.ssl.keyStore=keystore
-Djavax.net.ssl.keyStoreType=PKCS12
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.debug=SSL,handshake
-Djdk.tls.client.protocols=TLSv1.3
-Djdk.tls.server.protocols=TLSv1.3
-Dhttps.protocols=TLSv1.3
我用来调试这个问题的代码:
public static void main (String[] args) throws IOException {
URL url = new URL( "https://server.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
con.connect();
}
成功执行握手步骤的日志:
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.505 MSK|ClientHello.java:653|Produced ClientHello handshake message ("ClientHello": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.505 MSK|ServerHello.java:872|Consuming ServerHello handshake message ("ServerHello": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.505 MSK|ServerHello.java:968|Negotiated protocol version: TLSv1.3
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.536 MSK|ChangeCipherSpec.java:246|Consuming ChangeCipherSpec message
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.552 MSK|EncryptedExtensions.java:171|Consuming EncryptedExtensions handshake message (<...>)
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.552 MSK|CertificateRequest.java:926|Consuming CertificateRequest handshake message ("CertificateRequest": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.568 MSK|CertificateMessage.java:1171|Consuming server Certificate handshake message ("Certificate": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.677 MSK|CertificateVerify.java:1161|Consuming CertificateVerify handshake message ("CertificateVerify": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.677 MSK|Finished.java:898|Consuming server Finished handshake message ("Finished": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.693 MSK|CertificateMessage.java:1139|Produced client Certificate message ("Certificate": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.724 MSK|CertificateVerify.java:1126|Produced client CertificateVerify handshake message ("CertificateVerify": { <...> })
javax.net.ssl|DEBUG|01|main|2022-01-12 10:07:55.739 MSK|Finished.java:673|Produced client Finished handshake message ("Finished": { <...> })
在那之后我得到:
javax.net.ssl|ERROR|01|main|2022-01-12 11:38:54.523 MSK|TransportContext.java:341|Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking (
"throwable" : {
javax.net.ssl.SSLException: readHandshakeRecord
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1335)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
at SbbidIntegraionApplication.main(SbbidIntegraionApplication.java:17)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:251)
at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.onProduceFinished(Finished.java:679)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.produce(Finished.java:658)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.onConsumeFinished(Finished.java:1011)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.consume(Finished.java:874)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
... 6 more}
)
javax.net.ssl|WARNING|01|main|2022-01-12 11:38:54.523 MSK|TransportContext.java:383|Fatal: failed to send fatal alert HANDSHAKE_FAILURE (
"throwable" : {
java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:380)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
at SbbidIntegraionApplication.main(SbbidIntegraionApplication.java:17)}
)
javax.net.ssl|DEBUG|01|main|2022-01-12 11:38:54.523 MSK|SSLSocketImpl.java:1638|close the underlying socket
javax.net.ssl|DEBUG|01|main|2022-01-12 11:38:54.523 MSK|SSLSocketImpl.java:1657|close the SSL connection (initiative)
Exception in thread "main" javax.net.ssl.SSLException: readHandshakeRecord
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1335)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168)
at SbbidIntegraionApplication.main(SbbidIntegraionApplication.java:17)
Suppressed: java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:380)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
... 5 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:251)
at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.onProduceFinished(Finished.java:679)
at java.base/sun.security.ssl.Finished$T13FinishedProducer.produce(Finished.java:658)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.onConsumeFinished(Finished.java:1011)
at java.base/sun.security.ssl.Finished$T13FinishedConsumer.consume(Finished.java:874)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
... 6 more
Process finished with exit code 1
使用 curl 或 openssl 发送的相同请求已成功处理,我从服务器得到了预期的答复。
几乎在握手过程结束时出现这样的错误的原因是什么?
谢谢
更新:
在@dkotenko 发表评论后,我以编程方式初始化了 SSLContext:
public static void main (String []args) throws IOException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("keystore"), "changeit".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "changeit".toCharArray());
KeyStore trustStore = KeyStore.getInstance("PKCS12");
trustStore.load(new FileInputStream("cacerts"), "changeit".toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL("server.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
}
但得到了完全相同的输出。
已解决。问题是密钥库中没有 CA 证书。
服务器管理员说在 server.com 联系负载平衡器时会检查客户端证书链中是否有特定 root CA 的证书 .
导入keystore后,整个握手过程就完成了,收到了服务器的正确响应
希望有一天这会对某人有所帮助:)