连接到https站点时出现SSLHandshakeException

And*_*sne 4 java ssl jmeter sslhandshakeexception

我试图通过jmeter(版本2.13,java版本 - 1.8u31)记录https 网站,并在连接到https站点时收到SSLHandshakeException.错误消息是

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2011)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1113)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:436)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
    at org.apache.jmeter.protocol.http.sampler.MeasuringConnectionManager$MeasuredConnection.open(MeasuringConnectionManager.java:107)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:643)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:517)
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:331)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
    at org.apache.jmeter.protocol.http.proxy.Proxy.run(Proxy.java:240)  
Run Code Online (Sandbox Code Playgroud)

我打开了SSL的调试日志记录,但我无法理解根本原因.看来,Java客户端发送客户问候,但没有收到的服务器问候消息(其中服务器选择SSL的最高版本,最好的加密套件,无论是客户端和服务器支持,并将该信息发送给客户端).我发现客户端发送,读取和接收的协议版本之间存在差异(TLSv1.1与TLSv1.2)

这是根本原因吗?如果是这样,我该如何解决?

日志粘贴在这里 - Java SSLHandshakeException日志 - Pastebin.com

更新

正如@Anand Bhatt建议的那样,我用ssllabs分析了网站并理解了以下内容

  1. 服务器不支持java 8支持的TLSv1.2
  2. 服务器仅支持一个密码套件 - TLS_RSA_WITH_AES_256_CBC_SHA
  3. Java 8u31不支持服务器支持的密码套件,这很可能是问题所在.

听起来不错吗?如果是这样,我们如何让java 8客户端支持服务器支持的密码套件?

dav*_*085 7

SSLlabs显然正在测试"开箱即用"的支持.Java加密有一个可以追溯到20世纪90年代的时候,当时美国政府严格限制加密软件的出口,结果由当时Sun分发的JRE(或JDK)- Oracle不允许使用256位对称加密,您的服务器要求.您必须为您的Java(主要)版本下载并安装" JCE Unlimited Strength Jurisdiction Policy Files"; 8位于http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html.文件中的README提供了longwinded细节,但基本上你在JRE/lib/security中替换了两个小的jar文件.

TLSv1.2工作是不是一个真正的问题现在.TLS协议自动协商两端支持(和启用)的最高版本.Java 8 实现了 SSLv3,TLSv1.0,TLSv1.1和TLSv1.2,但最近的更新(8u31或7u75及更高版本)默认禁用 SSLv3 ,因为POODLE; 你可以选择重新启用它,但你应该不愿意.(Java 7实现了相同的协议版本,但默认情况下客户端禁用1.1和1.2,因为几年前它的版本存在兼容性问题.)

但是,由于POODLE和BEAST,一些安全机构不再接受SSLv3和TLSv1.0作为足够安全的; 一个重要的例子是信用卡和借记卡,详见https://security.stackexchange.com/a/87077/39571.TLSv1.2包括一些超过1.1的技术改进,使其成为今天的首选,并且可能有未来的发现使这些改进至关重要; 如果你的服务器在那时不能支持1.2(也许更高)你就会遇到麻烦.类似地,服务器唯一支持的套件使用普通RSA密钥交换(即非前向保密)的事实现在被认为是次优的,并且随着时间的推移可能变得不可接受.

keytool(至少使用常用的密钥库和信任库文件)与对称加密无关.如果服务器使用您的JRE和/或应用程序不信任的CA根(或更准确,更通用,信任锚),和/或服务器需要SSL/TLS级别的客户端身份验证 ,则可能是相关的,这是相当罕见的.(大部分网站在Web应用程序级别认证,或至少HTTP的水平,如果在所有.)SSLLabs服务器证书链的检查(和一些其他的东西也)通常比Java的更严格,而他们并没有抱怨区域,所以你不太可能遇到问题.

  • 突发新闻:[Java 9 中不需要它们!](http://www.oracle.com/technetwork/java/javase/terms/readme/jdk9-readme-3852447.html#jce) (2认同)
  • @FranklinYu:甚至更多(10 月):也不是 8u151+。但是关于 JCE-128bits 问题的各种堆栈可能有一百多个答案;如果你想修复所有这些,那将是一项艰巨的工作。我已经决定只将新的事实放在新的答案中。 (2认同)