Ssl 使用AES_256_CBC_SHA256密码套件启用TLSv1.2和TLS_RSA_

Ssl 使用AES_256_CBC_SHA256密码套件启用TLSv1.2和TLS_RSA_,ssl,encryption,java-7,tls1.2,java-security,Ssl,Encryption,Java 7,Tls1.2,Java Security,当我尝试通过SSL直接从客户端连接到服务器时,我收到以下错误: Server: TLS Version: v1.2 Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 Client: JRE 1.7 下面的代码启用TLSv1.2 Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at sun.security

当我尝试通过SSL直接从客户端连接到服务器时,我收到以下错误:

Server: 
TLS Version: v1.2
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 

Client:
JRE 1.7
下面的代码启用TLSv1.2

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)
我正在执行与以下类似的程序:

-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\u RSA\u WITH_AES\u 256\u CBC\u SHA256 Ddeployment.security.TLSv1.2=true-Djavax.net.debug=ssl:handshake SSLPoker.jar 443
SSLPoker包含以下代码:

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
package com.ashok.ssl;
导入javax.net.ssl.SSLSocket;
导入javax.net.ssl.SSLSocketFactory;
导入java.io.*;
/**
*建立到主机和端口的SSL连接,写入一个字节并打印响应-Ashok Goli。看见
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+服务
*/
公共级SSLPoke{
/**
*主要方法。
*用法:$java-jar-SSLPoker.jar
*
*@param将参数设置为args
*/
公共静态void main(字符串[]args){
如果(参数长度!=2){
System.out.println(“用法:“+SSLPoke.class.getName()+”);
系统出口(1);
}
试一试{
SSLSocketFactory SSLSocketFactory=(SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket SSLSocket=
(SSLSocket)sslsocketfactory.createSocket(args[0],Integer.parseInt(args[1]);
InputStream in=sslsocket.getInputStream();
OutputStream out=sslsocket.getOutputStream();
//写入测试字节以获得反应:)
写出(1);
while(in.available()>0){
System.out.print(in.read());
}
System.out.println(“成功连接”);
}捕获(异常){
异常。printStackTrace();
}
}
}

任何关于如何在不更改Java代码的情况下实现这一点的建议都将不胜感激。

只有在使用属性的简单HTTPS连接(而不是SSL套接字)时才有可能

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();
    }
  }
}

Java7引入了对TLSV1.2的支持(参见 ) 但默认情况下不启用它。换句话说,你的客户端应用程序 必须在SSLContext创建时明确指定“TLS v1.2”,或 否则就无法使用它

如果需要直接使用安全套接字协议,请在应用程序启动时创建“TLSv1.2”SSLContext,并使用SSLContext.setDefault(ctx)调用将该新上下文注册为默认上下文

-Dhttps.protocols=TLSv1.2 
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256

默认情况下,JRE禁用所有256位加密。要启用此功能,您可以在此处下载Java加密扩展(JCE)无限强度权限策略文件


local_policy.jarUS_export_policy.jarjars文件替换到jre目录中的lib/security中。

看起来当前jre在
lib/security
中的jre安装文件夹下提供了有限和无限策略文件,每个文件都在单独的子文件夹中。默认情况下,在
lib/security/java.security
中,默认使用
limited
策略。但是,如果您取消注释
crypto.policy=unlimited
行,这将允许Java使用
unlimited
策略文件并启用256位密码/算法。

如果不添加整个安全提供程序(如Bouncy Castle),就无法添加TLS密码套件,我需要使用什么设置来实现这一点?我确实添加了TLS,并使用上面的代码成功连接到服务器。Ashok+@EJP:你不需要Bouncy,而且不管怎样,对于单个SSL/TLS套件没有JCA/provider接口,只有整个协议。Java7JSSE支持开箱即用的套件。事实上,它在默认情况下已经启用,所以您不需要启用它,而TLSv1.2在默认情况下已经为服务器端启用,所以您不需要启用它。但所有使用256位数据密码的套件只有在安装了无限强度管辖权策略文件(JRE/lib/security中的2个JAR)时才会使用;是吗?对于您的客户端,
https.
属性仅适用于由
HttpsURLConnection
建立的连接,即来自
URLConnection
的连接,其方案为
https:
。使用
SSLSocketFactory
的“仅SSL/TLS”连接不使用它们。对于这些方法,您必须在创建套接字之后以及执行任何输入、输出或(显式)
.startAndShake()
.Wow之前调用套接字上的
.setEnabled*
方法。。。这确实是需要的。我注意到它们被忽略了,但并不期望服务器已经需要TLS 1.2这仅适用于(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
文件中不存在。
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();
    }
  }
}
-Dhttps.protocols=TLSv1.2 
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256
SSLContext context = SSLContext.getInstance("TLSv1.2");
SSLContext.setDefault(context);