通过 SSLHandshakeException 接收到致命警报: handshake_error

我有一个问题与授权 SSL 连接。我已经创建了使用客户端授权 SSL 证书连接到外部服务器的 Struts Action。在我的行动,我试图发送一些数据到银行服务器,但没有任何运气,因为我有作为一个结果,从服务器以下错误:

error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

将数据发送到服务器的 Action 类中的

//Getting external IP from host
URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader inIP = new BufferedReader(new InputStreamReader(whatismyip.openStream()));


String IPStr = inIP.readLine(); //IP as a String


Merchant merchant;


System.out.println("amount: " + amount + ", currency: " + currency + ", clientIp: " + IPStr + ", description: " + description);


try {


merchant = new Merchant(context.getRealPath("/") + "merchant.properties");


} catch (ConfigurationException e) {


Logger.getLogger(HomeAction.class.getName()).log(Level.INFO, "message", e);
System.err.println("error: " + e.getMessage());
return ERROR;
}


String result = merchant.sendTransData(amount, currency, IPStr, description);


System.out.println("result: " + result);


return SUCCESS;

我的 merchant.properties 文件:

bank.server.url=https://-servernameandport-/
https.cipher=-cipher-


keystore.file=-key-.jks
keystore.type=JKS
keystore.password=-password-
ecomm.server.version=2.0


encoding.source=UTF-8
encoding.native=UTF-8

我第一次认为这是一个证书问题,我将它从。Pfx 到。Jks,但我有同样的错误,没有改变。

737255 次浏览

握手失败可能是由于各种原因:

  • 客户端和服务器使用的不兼容的密码套件。这将要求客户端使用(或启用)服务器支持的密码套件。
  • 正在使用的不兼容的 SSL 版本(服务器可能只接受 TLS v1,而客户机只能使用 SSL v3)。同样,客户机可能必须确保使用 SSL/TLS 协议的兼容版本。
  • 服务器证书的信任路径不完整; 客户端可能不信任服务器证书。这通常会导致更详细的错误,但这是很有可能的。通常的修复方法是将服务器的 CA 证书导入到客户机的信任存储中。
  • 该证书是为不同的域颁发的。同样,这将导致更详细的消息,但我将在这里说明修复,以防这是原因。在这种情况下,解决方案是让服务器(看起来不是您的服务器)使用正确的证书。

由于无法查明潜在的故障,所以最好打开 -Djavax.net.debug=all标志以启用已建立的 SSL 连接的调试。打开调试之后,您就可以确定握手中的哪个活动失败了。

更新

根据现有的详细信息,问题似乎是由于发给服务器的证书与根 CA 之间的证书信任路径不完整所致。在大多数情况下,这是因为根 CA 的证书在信任存储中不存在,导致证书信任路径不存在; 证书基本上不受客户端的信任。浏览器可以提供一个警告,以便用户可以忽略它,但 SSL 客户端(如 HttpsURLConnection类或任何 HTTP 客户端库如 Apache 客户端)的情况并非如此。

大多数这些客户机类/库将依赖 JVM 使用的信任存储区进行证书验证。在大多数情况下,这将是 JRE _ HOME/lib/security 目录中的 cacerts文件。如果使用 JVM 系统属性 javax.net.ssl.trustStore指定了信任存储区的位置,则该路径中的存储区通常是客户端库使用的存储区。如果您有疑问,请查看您的 Merchant类,并找出它用来建立连接的类/库。

将服务器的证书颁发 CA 添加到这个信任存储应该可以解决这个问题。为此,您可以参考我的 回答一个关于获取工具的相关问题,但是 Java keytool 实用程序已经足够了。

警告 : 信任存储区本质上是您所信任的所有 CA 的列表。如果您输入的证书不属于您不信任的 CA,那么如果私钥可用,则可以对 SSL/TLS 连接到具有该实体颁发的证书的站点进行解密。

更新 # 2: 理解 JSSE 跟踪的输出

JVM 使用的密钥存储库和信任存储库通常在开头列出,有点像下面这样:

keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: C:\Java\jdk1.6.0_21\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is :

如果使用了错误的信任存储库,那么您需要将服务器的证书重新导入到正确的证书,或者重新配置服务器以使用列出的证书(如果您有多个 JVM,并且所有这些证书都用于不同的需求,则不推荐使用)。

如果您想要验证信任证书列表是否包含所需的证书,那么有一个相同的部分,其开头如下:

adding as trusted cert:
Subject: CN=blah, O=blah, C=blah
Issuer:  CN=biggerblah, O=biggerblah, C=biggerblah
Algorithm: RSA; Serial number: yadda
Valid from SomeDate until SomeDate

您需要查看服务器的 CA 是否是主题。

握手过程将有几个显著的条目(您需要了解 SSL 才能详细地理解它们,但是为了调试当前问题,只要知道在 ServerHello 中通常会报告握手失败就足够了。

1. 客户你好

连接初始化时将报告一系列条目。客户机在 SSL/TLS 连接设置中发送的第一条消息是 ClientHello 消息,通常在日志中报告如下:

*** ClientHello, TLSv1
RandomCookie:  GMT: 1291302508 bytes = { some byte array }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods:  { 0 }
***

请注意所使用的密码套件。对于同样的约定,带有 merchant.properties 文件中的条目的 可能不得不同意可能会被银行的库所使用。如果使用的约定不同,则不必担心,因为如果密码套件不兼容,ServerHello 将会这样说。

2. ServerHello

服务器使用 ServerHello 进行响应,它将指示连接设置是否可以继续。日志中的条目通常类型如下:

*** ServerHello, TLSv1
RandomCookie:  GMT: 1291302499 bytes = { some byte array}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
***

请注意它所选择的密码套件; 这是服务器和客户机都可以使用的最佳套件。如果出现错误,通常不指定密码组合。服务器的证书(以及可选的整个链)由服务器发送,在条目中可以找到:

*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=server, O=server's org, L=server's location, ST =Server's state, C=Server's country
Signature Algorithm: SHA1withRSA, OID = some identifer


.... the rest of the certificate
***

如果证书的验证成功,您会发现一个类似于:

Found trusted certificate:
[
[
Version: V1
Subject: OU=Server's CA, O="Server's CA's company name", C=CA's country
Signature Algorithm: SHA1withRSA, OID = some identifier

上面的步骤之一不会成功,导致握手失败,因为握手通常在这个阶段完成(实际上不是,但是握手的后续阶段通常不会导致握手失败)。您需要找出哪个步骤失败了,并将适当的消息作为问题的更新发布(除非您已经理解了该消息,并且知道如何解决该消息)。

当客户端需要提供证书时,也会发生这种情况。在服务器列出证书链之后,可能会发生以下情况:

3. 证书申请 服务器将从客户端发出证书请求。请求将列出服务器接受的所有证书。

*** CertificateRequest
Cert Types: RSA
Cert Authorities:
<CN=blah, OU=blah, O=blah, L=blah, ST=blah, C=blah>
<CN=yadda, DC=yadda, DC=yadda>
<CN=moreblah, OU=moreblah, O=moreblah, C=moreblah>
<CN=moreyada, OU=moreyada, O=moreyada, C=moreyada>
... the rest of the request
*** ServerHelloDone

4. 客户证书链 这是客户端发送到服务器的证书。

*** Certificate chain
chain [0] = [
[
Version: V3
Subject: EMAILADDRESS=client's email, CN=client, OU=client's ou, O=client's Org, L=client's location, ST=client's state, C=client's Country
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
... the rest of the certificate
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
... key exchange info

如果链中没有证书,而服务器需要证书,您将在这里看到握手错误。一个可能的原因是没有找到您的证书路径。

5. 验证证书 客户端要求服务器验证证书

*** CertificateVerify
... payload of verify check

只有在发送证书时才会执行此步骤。

6. 完成 服务器将以验证响应进行响应

*** Finished
verify_data:  { 345, ... }

我不认为这解决了第一个提问者的问题,但对于来这里寻求答案的谷歌人来说:


在更新51中,java 1.8默认禁止[1] RC4密码,我们可以在发布说明页面上看到:

错误修复: 禁止 RC4密码套件

RC4现在被认为是一个被破解的密码。

在 Oracle JSSE 实现中,RC4密码套件已从客户端和服务器默认启用的密码套件列表中删除。这些密码套件仍然可以通过 SSLEngine.setEnabledCipherSuites()SSLSocket.setEnabledCipherSuites()方法启用。请参阅 JDK-8077109(非公开)。

如果您的服务器对这个密码有强烈的偏好(或者只使用这个密码) ,这可能会在 java 上触发 handshake_failure

您可以测试连接到启用 RC4密码的服务器(首先,尝试不使用 enabled参数来查看是否触发 handshake_failure,然后设置 enabled:

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;


import java.util.Arrays;


/** Establish a SSL connection to a host and port, writes a byte and
* prints the response. See
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services
*/
public class SSLRC4Poke {
public static void main(String[] args) {
String[] cyphers;
if (args.length < 2) {
System.out.println("Usage: "+SSLRC4Poke.class.getName()+" <host> <port> enable");
System.exit(1);
}
try {
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
        

cyphers = sslsocketfactory.getSupportedCipherSuites();
if (args.length ==3){
sslsocket.setEnabledCipherSuites(new String[]{
"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
"SSL_DH_anon_WITH_RC4_128_MD5",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_WITH_RC4_128_MD5",
"SSL_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
"TLS_ECDH_RSA_WITH_RC4_128_SHA",
"TLS_ECDH_anon_WITH_RC4_128_SHA",
"TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
"TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
"TLS_KRB5_WITH_RC4_128_MD5",
"TLS_KRB5_WITH_RC4_128_SHA"
});
}


InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();


// Write a test byte to get a reaction :)
out.write(1);


while (in.available() > 0) {
System.out.print(in.read());
}
System.out.println("Successfully connected");


} catch (Exception exception) {
exception.printStackTrace();
}
}
}

1-https://www.java.com/en/download/faq/release_changes.xml

今天我遇到了同样的问题,用 OkHttp 客户端获取一个基于 https 的 URL。

1)查阅你的网站的 https 协议版本及密码方法。

openssl>s_client -connect your_website.com:443 -showcerts

您将获得许多详细信息,关键信息列出如下:

SSL-Session:
Protocol  : TLSv1
Cipher    : RC4-SHA
2)配置您的 http 客户端,例如,在 OkHttp 客户端的情况下:
@Test()
public void testHttpsByOkHttp() {
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_0) //protocol version
.cipherSuites(
CipherSuite.TLS_RSA_WITH_RC4_128_SHA, //cipher method
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();


OkHttpClient client = new OkHttpClient();
client.setConnectionSpecs(Collections.singletonList(spec));
Request request = new Request.Builder().url("https://your_website.com/").build();
try {
Response response = client.newCall(request).execute();
if(response.isSuccessful()){
logger.debug("result= {}", response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}

这会得到我们想要的。

我在尝试使用 JDK 1.7时出现了这个错误。 当我将 JDK 升级到 jdk1.8.0 _ 66时,一切都开始正常运行。

所以这个问题最简单的解决方案可以是-升级你的 JDK,它可以开始很好地工作。

免责声明: 我不知道这个答案是否对很多人有帮助,只是分享,因为它可能有帮助。

我在使用 Parasoft SOATest 发送请求 XML (SOAP)时遇到了这个错误。

问题是,在添加证书并对其进行身份验证之后,我从下拉列表中得到了 选错了化名

我的是一个 TLS版本不兼容的错误。

以前它是 TLSv1我改变了它 TLSV1.2这解决了我的问题。

我正在使用 com.google.api http client。当我与公司内部网站通信时,我错误地使用了 https 而不是 http,从而导致了这个问题。

main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, IOException in getSession():  javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
main, called close()
main, called closeInternal(true)
262 [main] DEBUG org.apache.http.impl.conn.DefaultClientConnection  - Connection shut down
main, called close()
main, called closeInternal(true)
263 [main] DEBUG org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager  - Released connection is not reusable.
263 [main] DEBUG org.apache.http.impl.conn.tsccm.ConnPoolByRoute  - Releasing connection [HttpRoute[{s}->https://<I-replaced>]][null]
263 [main] DEBUG org.apache.http.impl.conn.tsccm.ConnPoolByRoute  - Notifying no-one, there are no waiting threads
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:431)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:339)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at com.google.api.client.http.apache.ApacheHttpRequest.execute(ApacheHttpRequest.java:67)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:960)

假设您正在使用适当的 SSL/TLS 协议,正确配置了 keyStoretrustStore,并确认证书本身不存在任何问题,那么您可能需要使用 加强你的安全算法

正如在 维尼特的回答中提到的,您收到此错误的一个可能原因是由于使用了不兼容的密码套件。通过使用 Java 加密扩展(JCE)中提供的文件夹更新 JDK 的 security文件夹中的 local_policyUS_export_policy罐,我能够成功地完成握手。

握手失败可能是 TLSv1协议实现出错。

在我们的案例中,这对 java 7有所帮助:

java -Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1

Jvm 将按照这个顺序进行谈判。带有最新更新的服务器将执行1.2版本,带有 bug 的服务器将执行 v1版本,这将与 java 7中类似的 v1版本一起工作。

安装 Java 加密扩展(JCE)无限强度(JDK7 | 适用于 JDK8)可能会修复这个错误。解压缩文件并按照自述文件安装它。

我也遇到过类似的问题; 升级到 ApacheHTTPClient 4.5.3解决了这个问题。

我发现一个 HTTPS 服务器以这种方式失败,如果我的 Java 客户端进程配置为

-Djsse.enableSNIExtension=false

ServerHello成功完成之后,但在数据流启动之前,与 handshake_failure的连接失败。

没有明确的错误消息来识别问题,这个错误看起来就像

main, READ: TLSv1.2 Alert, length = 2
main, RECV TLSv1.2 ALERT:  fatal, handshake_failure
%% Invalidated:  [Session-3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

我通过尝试使用和不使用“ -Djsse.enableSNIExtension=false”选项来隔离这个问题

在我的例子中,cert 被导入,错误仍然存在,通过在连接之前添加 System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");解决了这个问题

呃!这对我来说只是一个 Java 版本的问题。我在使用 JRE1.6时出现了握手错误,而在使用 JRE1.8.0 _ 144时一切正常。

在我的情况下,网站只能使用 TLSv1.2。我使用 apache httpclient 4.5.6,我使用这段代码并安装 jce 来解决这个问题(JDK1.7) :

Jce

Jdk7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

JDK 8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

密码:

SSLContext sslContext = SSLContext.getDefault();


SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2"}, // important
null,
NoopHostnameVerifier.INSTANCE);


Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionFactory)
.register("http", PlainConnectionSocketFactory.INSTANCE)
.build();


HttpClientConnectionManager ccm = new BasicHttpClientConnectionManager(registry);
httpclient = HttpClientBuilder.create().
.setSSLSocketFactory(sslConnectionFactory)
.setConnectionManager(ccm)
.build();

从开发人员(项目1)和系统管理员(项目2和3)的角度进行故障排除:

  1. 通过 -Djavax.net.debug=ssl:handshake:verbose在 Java 中启用 SSL 握手调试。
  2. 通过 sudo apt install ssldump在服务器上安装 ssldump,如果在运行以下步骤时观察到密码中的 Unknown value,则按照此 链接从源代码进行编译。
  3. 在服务器,sudo ssldump -k <your-private-key> -i <your-network-interface>
  4. 检查有关实际 原因故障的日志。

Ssldump 日志的不工作握手示例:

New TCP connection #1: 10.1.68.86(45308) <-> 10.1.68.83(5671)
1 1  0.0111 (0.0111)  C>S  Handshake
ClientHello
Version 3.3
cipher suites
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
compression methods
NULL
1 2  0.0122 (0.0011)  S>C  Alert
level           fatal
value           insufficient_security
1    0.0126 (0.0004)  S>C  TCP RST

成功握手 ssldump 日志的示例

New TCP connection #1: 10.1.68.86(56558) <-> 10.1.68.83(8443)
1 1  0.0009 (0.0009)  C>S  Handshake
ClientHello
Version 3.3
cipher suites
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Unknown value 0xcca9
Unknown value 0xcca8
Unknown value 0xccaa
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
compression methods
NULL
1 2  0.0115 (0.0106)  S>C  Handshake
ServerHello
Version 3.3
session_id[0]=


cipherSuite         TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
compressionMethod                   NULL
1 3  0.0115 (0.0000)  S>C  Handshake
Certificate
1 4  0.0115 (0.0000)  S>C  Handshake
ServerKeyExchange
Not enough data. Found 294 bytes (expecting 32767)
1 5    0.0115   (0.0000)    S>C    Handshake
ServerHelloDone
1 6    0.0141   (0.0025)    C>S    Handshake
ClientKeyExchange
Not enough data. Found 31 bytes (expecting 16384)
1 7    0.0141   (0.0000)    C>S    ChangeCipherSpec
1 8    0.0141   (0.0000)    C>S      Handshake
1 9    0.0149   (0.0008)    S>C    Handshake
1 10   0.0149   (0.0000)    S>C    ChangeCipherSpec
1 11   0.0149   (0.0000)    S>C      Handshake

无法使用 Java 日志的示例

javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.778 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.779 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.779 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.780 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.780 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.780 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.781 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.781 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.781 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.782 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.782 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.782 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.782 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.783 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.783 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.783 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.783 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.783 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: T LS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLS11
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.784 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.785 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLS10 javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.786 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLS10
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.787 MYT|HandshakeContext.java:294|Ignore unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLS10
javax.net.ssl|WARNING|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.818 MYT|SignatureScheme.java:282|Signature algorithm, ed25519, is not supported by the underlying providers
javax.net.ssl|WARNING|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.818 MYT|SignatureScheme.java:282|Signature algorithm, ed448, is not supported by the underlying providers
javax.net.ssl|ALL|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.822 MYT|SignatureScheme.java:358|Ignore disabled signature sheme: rsa_md5
javax.net.ssl|INFO|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.822 MYT|AlpnExtension.java:161|No available application protocols
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.823 MYT|SSLExtensions.java:256|Ignore, context unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.823 MYT|SSLExtensions.java:256|Ignore, context unavailable extension: renegotiation_info
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.825 MYT|ClientHello.java:651|Produced ClientHello handshake message (
"ClientHello": {
"client version"      : "TLSv1.2",
"random"              : "FB BC CD 7C 17 65 86 49 3E 1C 15 37 24 94 7D E7 60 44 1B B8 F4 18 21 D0 E1 B1 31 0D E1 80 D6 A7",
"session id"          : "",
"cipher suites"       : "[TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B), TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384(0xC030), TLS_RSA_WITH_AES_256_GCM_SHA384(0x009D), TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384(0xC02E), TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384(0xC032), TLS_DHE_RSA_WITH_AES_256_GCM_SHA384(0x009F), TLS_DHE_DSS_WITH_AES_256_GCM_SHA384(0x00A3), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(0xC02F), TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C), TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256(0xC02D), TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256(0xC031), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256(0x009E), TLS_DHE_DSS_WITH_AES_128_GCM_SHA256(0x00A2), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(0xC024), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(0xC028), TLS_RSA_WITH_AES_256_CBC_SHA256(0x003D), TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384(0xC026), TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384(0xC02A), TLS_DHE_RSA_WITH_AES_256_CBC_SHA256(0x006B), TLS_DHE_DSS_WITH_AES_256_CBC_SHA256(0x006A), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA(0xC005), TLS_ECDH_RSA_WITH_AES_256_CBC_SHA(0xC00F), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_DHE_DSS_WITH_AES_256_CBC_SHA(0x0038), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(0xC023), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(0xC027), TLS_RSA_WITH_AES_128_CBC_SHA256(0x003C), TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256(0xC025), TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256(0xC029), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(0x0067), TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(0x0040), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA(0xC004), TLS_ECDH_RSA_WITH_AES_128_CBC_SHA(0xC00E), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033), TLS_DHE_DSS_WITH_AES_128_CBC_SHA(0x0032), TLS_EMPTY_RENEGOTIATION_INFO_SCSV(0x00FF)]",
"compression methods" : "00",  "extensions"          : [
"server_name (0)": {
type=host_name (0), value=mq.tpc-ohcis.moh.gov.my
},
"status_request (5)": {
"certificate status type": ocsp
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
},
"supported_groups (10)": {
"versions": [secp256r1, secp384r1, secp521r1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1, secp256k1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
},
"ec_point_formats (11)": {
"formats": [uncompressed]
},
"signature_algorithms (13)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp512r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha224, rsa_sha224, dsa_sha224, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"signature_algorithms_cert (50)": {
"signature schemes": [ecdsa_secp256r1_sha256, ecdsa_secp384r1_sha384, ecdsa_secp512r1_sha512, rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512, rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512, dsa_sha256, ecdsa_sha224, rsa_sha224, dsa_sha224, ecdsa_sha1, rsa_pkcs1_sha1, dsa_sha1]
},
"status_request_v2 (17)": {
"cert status request": {
"certificate status type": ocsp_multi
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}      }
},
"extended_master_secret (23)": {
<empty>
},
"supported_versions (43)": {
"versions": [TLSv1.2, TLSv1.1, TLSv1]
}
]
}
)
javax.net.ssl|DEBUG|43|SimpleAsyncTaskExecutor-1|2019-07-03 17:35:01.829 MYT|Alert.java:238|Received alert message (
"Alert": {
"level"      : "fatal",
"description": "insufficient_security"
}
)

在我的例子中,1.1版本有一个问题。我用卷发很容易地重现了这个问题。服务器不支持低于 TLS1.2的版本。

接到的握手信号是:

curl --insecure --tlsv1.1 -i https://youhost --noproxy "*"

在1.2版本中工作良好:

curl --insecure --tlsv1.2 -i https://youhost --noproxy "*"

服务器正在运行一个 Weblogic,在 setEnvDomain.sh 中添加这个参数使它能够与 TLSv1.1一起工作:

-Dweblogic.security.SSL.minimumProtocolVersion=TLSv1.1

这个问题是由 Java 版本引起的。我使用的是1.8.0.231 JDK 并得到了这个错误。我已经将我的 java 版本从1.8.0.231降级到1.8.0.171,现在它工作得很好。

在检查时我发现问题是 java 7,当我把它改成 java 8后,它开始工作了。下面一个是有问题的版本。

java -version
java version "1.7.0_101"
Java(TM) SE Runtime Environment (build 1.7.0_101-b61)
Java HotSpot(TM) 64-Bit Server VM (build 24.101-b61, mixed mode)