ssl - 启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件

标签 ssl encryption java-7 tls1.2 java-security

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.2TLS_RSA_WITH_AES_256_CBC_SHA256 而无需通过属性、参数或 Debug Prop 更改任何 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 代码的情况下实现这一点的指示将不胜感激。

最佳答案

仅当您使用属性使用简单的 HTTPS 连接(而非 SSL 套接字)时才有可能

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

请参阅 http://fsanglier.blogspot.com.es/ 上的帖子

Java 7 introduced support for TLS v1.2 (refer to http://docs.oracle.com/javase/7/docs/technotes/guides/security/enhancements-7.html) BUT does not enable it by default. In other words, your client app must explicitly specify "TLS v1.2" at SSLContext creation, or otherwise will just not be able to use it.

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

SSLContext context = SSLContext.getInstance("TLSv1.2");
SSLContext.setDefault(context);

关于ssl - 启用 TLSv1.2 和 TLS_RSA_WITH_AES_256_CBC_SHA256 密码套件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33089150/

相关文章:

带有客户端证书的 Apache "SSLSessionCacheTimeout"

ssl - 无法在我的应用程序中使用自签名证书,但可以与 s_client 一起使用

c# - 如何使用 .net 创建加密文件容器

encryption - GCP Cloud Memorystore 静态数据加密

migration - java 7升级和休眠注释处理器错误

java - jdk7 32位windows版下载

c++ - 初始化 SSL 和 libcurl 并获取 "out of memory"

c++ - Windows 上的 TLS 客户端和服务器 [openssl vs. sspi vs. cryptlib]

linux - 检测 cryptofs 设备或分区

backwards-compatibility - JDK6 库 - 与 JDK7 的兼容性