启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件
Posted
技术标签:
【中文标题】启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件【英文标题】:Enable TLSv1.2 and TLS_RSA_WITH_AES_256_CBC_SHA256 Cipher Suite 【发布时间】:2016-01-10 09:44:33 【问题描述】:Server:
TLS Version: v1.2
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Client:
JRE 1.7
当我尝试通过 SSL 直接从客户端连接到服务器时收到以下错误:
Caused by: 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)
以下代码启用 TLSv1.2
Set<String> enabledTLSSet = new HashSet<String>(Arrays.asList(sslsocket.getEnabledProtocols()));
enabledTLSSet.add("TLSv1.2");
sslsocket.setEnabledProtocols(enabledTLSSet.toArray(new String[enabledTLSSet.size()]));
以下代码启用 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件:
Set<String> enabledCipherSuitesSet = new HashSet<String>(Arrays.asList(sslsocket.getEnabledCipherSuites()));
enabledCipherSuitesSet.add("TLS_RSA_WITH_AES_256_CBC_SHA256");
sslsocket.setEnabledCipherSuites(enabledCipherSuitesSet.toArray(new String[enabledCipherSuitesSet.size()]));
从 Java 代码完成上述两项操作后,我可以通过 SSL 成功连接到服务器。
是否可以在 Java 7 中启用/强制 TLSv1.2
和 TLS_RSA_WITH_AES_256_CBC_SHA256
而无需通过属性、参数或调试道具更改任何 Java 代码?
我以所有形式和组合(启用和禁用)尝试了以下所有属性,但失败了。
-Dhttps.protocols=TLSv1.2
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256
-Ddeployment.security.TLSv1.2=true
我正在执行类似于下面的程序:
java -jar -Dhttps.protocols=TLSv1.2 -Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256 Ddeployment.security.TLSv1.2=true -Djavax.net.debug=ssl:handshake SSLPoker.jar <SERVER> 443
SSLPoker 包含以下代码:
package com.ashok.ssl;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
/**
* Establish a SSL connection to a host and port, writes a byte and prints the response - Ashok Goli. See
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services
*/
public class SSLPoke
/**
* The main method.
* Usage: $java -jar SSLPoker.jar <host> <port>
*
* @param args the arguments
*/
public static void main(String[] args)
if (args.length != 2)
System.out.println("Usage: " + SSLPoke.class.getName() + " <host> <port>");
System.exit(1);
try
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket =
(SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
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();
任何关于如何在不更改 Java 代码的情况下实现此目的的指针将不胜感激。
【问题讨论】:
如果不添加完整的安全提供程序(例如 Bouncy Castle,它确实可能支持该安全提供程序),则无法添加 TLS 密码套件。 我需要使用哪些设置来实现这一目标? 我确实添加了 TLS 并使用上面的代码成功连接到服务器。只是在寻找一种通过配置来做到这一点的方法。 Ashok + @EJP:你不需要 Bouncy,而且无论如何都没有针对单个 SSL/TLS 套件的 JCA/提供者接口,只有整个协议。 Java7 JSSE 开箱即用地支持该套件。事实上它已经默认启用所以你不需要启用它,并且TLSv1.2已经默认为 server 端启用所以你不需要启用它。但所有使用 256 位数据密码的套件只有在安装了 无限强度管辖权政策文件(JRE/lib/security 中的 2 个 jars)后才能使用;是吗? 对于您的客户端,https.*
属性仅适用于由HttpsURLConnection
建立的连接,即来自URLConnection
的连接,其URL 的方案为https:
。与SSLSocketFactory
的“Just-SSL/TLS”连接不使用它们。对于那些您必须在创建套接字之后和执行任何输入、输出或(显式).startHandshake()
之前调用套接字上的 .setEnabled*
方法。
【参考方案1】:
仅当您使用属性使用简单的 HTTPS 连接(不是 SSL 套接字)时才有可能
-Dhttps.protocols=TLSv1.2
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256
查看http://fsanglier.blogspot.com.es/的帖子
Java 7 引入了对 TLS v1.2 的支持(请参阅 http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html) 但默认情况下不启用它。换句话说,您的客户端应用程序 必须在 SSLContext 创建时明确指定“TLS v1.2”,或者 否则将无法使用它。
如果您需要直接使用安全套接字协议,请在应用程序启动时创建一个“TLSv1.2”SSLContext,并使用 SSLContext.setDefault(ctx) 调用将该新上下文注册为默认上下文。
SSLContext context = SSLContext.getInstance("TLSv1.2");
SSLContext.setDefault(context);
【讨论】:
哇...这确实是必需的。我注意到它们被忽略了,但没想到服务器已经需要 TLS 1.2【参考方案2】:看起来当前 JRE 在 lib/security
的 JRE 安装文件夹下提供了有限和无限策略文件,每个文件都位于单独的子文件夹中。默认情况下,在lib/security/java.security
中,默认使用limited
策略。但是,如果您取消注释 crypto.policy=unlimited
行,这将允许 Java 使用 unlimited
策略文件并启用 256 位密码/算法。
【讨论】:
这仅适用于 (Oracle) 8u151/2(2017 年 9 月)。从 8u161/2(2017 年 12 月)开始,所有 9、10、11 都具有开箱即用的 policy=unlimited。 对于 Java 7 (jdk1.7.0_80) 不正确。crypto.policy
在 lib/security/java.security
文件中不存在。【参考方案3】:
JRE 默认禁用所有 256 位加密。要启用此功能,您可以在此处下载 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files:http://www.oracle.com/technetwork/java/javase/downloads/index.html
将 local_policy.jar 和 US_export_policy.jar jars 文件替换到 jre 目录下的 lib/security 中。
【讨论】:
以上是关于启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件的主要内容,如果未能解决你的问题,请参考以下文章
启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件
启用TLSv1.2和TLS_RSA_WITH_AES_256_CBC_SHA256密码套件