24
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 経由でサーバーに正常に接続できます。

TLSv1.2プロパティ、パラメーター、またはデバッグ小道具を使用してJavaコードを変更せずにTLS_RSA_WITH_AES_256_CBC_SHA256、Java 7で有効化/強制することは可能ですか?

以下のすべてのプロパティをすべての形式と組み合わせ (有効化と無効化) で試しましたが、失敗しました。

-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コードを変更せずにこれを達成する方法についての指針をいただければ幸いです。

4

3 に答える 3

19

プロパティを使用して単純な 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);
于 2016-06-01T18:47:56.800 に答える