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代码更改,如何实现这一目标的任何指针都将非常受欢迎。
答案 0 :(得分:16)
只有使用属性
使用简单的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) 但是默认情况下不启用它。换句话说,您的客户端应用程序 必须明确指定&#34; TLS v1.2&#34;在SSLContext创建,或 否则将无法使用它。
如果您需要直接使用安全套接字协议,请创建一个&#34; TLSv1.2&#34;应用程序启动时的SSLContext并使用SSLContext.setDefault(ctx)调用将新上下文注册为默认上下文。
SSLContext context = SSLContext.getInstance("TLSv1.2");
SSLContext.setDefault(context);
答案 1 :(得分:8)
JRE默认禁用所有256位加密。要使您能够在此处下载 Java密码术扩展(JCE)无限强度管辖权政策文件:http://www.oracle.com/technetwork/java/javase/downloads/index.html
将 local_policy.jar 和 US_export_policy.jar jars文件替换为jre目录中的lib / security。
答案 2 :(得分:2)
当前的JRE看起来像是"ms-appx:///Icons/Page2Icon.png"
中JRE的安装文件夹下的有限和无限制的政策文件,每个文件都位于不同的子文件夹中。默认情况下,在lib/security
中,默认使用lib/security/java.security
策略。但是,如果取消注释limited
行,这将允许Java使用crypto.policy=unlimited
策略文件并启用256位密码/算法。