问题
Server:
TLS Version: v1.2
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Client:
JRE 1.7
I am receiving the below error when I try to connect to the Server from Client through SSL directly:
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)
The below code enables TLSv1.2
Set<String> enabledTLSSet = new HashSet<String>(Arrays.asList(sslsocket.getEnabledProtocols()));
enabledTLSSet.add("TLSv1.2");
sslsocket.setEnabledProtocols(enabledTLSSet.toArray(new String[enabledTLSSet.size()]));
The below code enables TLS_RSA_WITH_AES_256_CBC_SHA256 Cipher Suite:
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()]));
After doing both of the above from Java code, I'm able to connect to the server successfully through SSL.
Is it possible to enable/force TLSv1.2
and TLS_RSA_WITH_AES_256_CBC_SHA256
in Java 7 without changing any Java Code through properties, parameters or Debug props?
I tried all of the below properties in all forms and combinations (enabling and disabling) and failed.
-Dhttps.protocols=TLSv1.2
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256
-Ddeployment.security.TLSv1.2=true
I'm executing the program similar to the below:
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 contains the below code:
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();
}
}
}
Any pointers how to achieve this with no Java code changes would be much appreciated.
回答1:
It is only possible if you use a simple HTTPS connection (not SSL Sockets) using the properties
-Dhttps.protocols=TLSv1.2
-Dhttps.cipherSuites=TLS_RSA_WITH_AES_256_CBC_SHA256
See the post at 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.
If you need to use directly secure socket protocol, create a "TLSv1.2" SSLContext at application startup and use the SSLContext.setDefault(ctx) call to register that new context as the default one.
SSLContext context = SSLContext.getInstance("TLSv1.2");
SSLContext.setDefault(context);
回答2:
The JREs disable all 256-bit crypto by default. To enable you can download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files here: http://www.oracle.com/technetwork/java/javase/downloads/index.html
Replace the local_policy.jar and US_export_policy.jar jars files into your lib/security in jre directory.
回答3:
It looks like current JRE's ship both the limited and unlimited policy files under the JRE's install folder in lib/security
, each in separate sub folders. By default, in lib/security/java.security
, the limited
policy is used by default. But if you uncomment the crypto.policy=unlimited
line, that will allow Java to use the unlimited
policy files and enable the 256-bit ciphers/algorithms.
来源:https://stackoverflow.com/questions/33089150/enable-tlsv1-2-and-tls-rsa-with-aes-256-cbc-sha256-cipher-suite