I encypted the session Id at server side but when I am trying to decrypt the session id at client side some error is coming. please can anyone help resolving the error.
public static String decrypt(String sessionId)
{
try
{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
final String decryptedSessionId = new String(cipher.doFinal(Base64.decodeBase64(sessionId)));
return decryptedSessionId;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
The error that is coming is :
Class 'javax.crypto.Cipher' is not present in JRE Emulation Library so it cannot be used in client code of "some" GWT module.
This inspection reports usages in client code of JDK classes which is not present in JRE Emulation Library.
The method for encryption that I used is :
public static String encrypt(String sessionId)
{
try
{
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
final SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
final String encryptedSessionId = Base64.encodeBase64String(cipher.doFinal(sessionId.getBytes()));
return encryptedSessionId;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
I am new to this stuff please help me resolving the errors
Well, you cannot use java standard encryption library in GWT coding on client side. It's not supported.
Use gwt-crypto to encrypt/decrypt the necessary stuff.
AES is not be supported on client side for GWT in GWT-crypto, but you can use TripleDES. TripleDES is also very much secure implementation.
I am running Java 8 and using com.sun.net.httpserver.HttpsServer to create a HTTPS server. I have a working implementation using a trusted CA signed EC certificate in a Java KeyStore.
I have been looking at how I could restrict what Ciphers and Protocols the server could support (similar to Apache using "SSLProtocol" and "SSLCipherSuite" in the configuration) - mainly to enforce a higher level of security by disabling the use of SHA-1.
No one should really be forcing TLSv1.1 over 1.2, but I am just doing this to prove a point that the following configuration works:
KeyStore ks = KeyStore.getInstance("JKS");
// Load KeyStore into "ks"
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, jksPassword.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
HttpsServer hsS = HttpsServer.create(sBind, 0);
hsS.setHttpsConfigurator(new HttpsConfigurator(sc) {
#Override
public void configure(HttpsParameters p) {
try {
SSLContext c = getSSLContext();
SSLEngine e = c.createSSLEngine();
p.setNeedClientAuth(false);
p.setProtocols(new String[] { "TLSv1.1" });
p.setCipherSuites(e.getEnabledCipherSuites());
p.setSSLParameters(c.getDefaultSSLParameters());
}
catch (Exception e) {
e.printStackTrace();
}
}
});
Even though I use setProtocols() to only accept "TLSv1.1", this doesn't seem to stop "TLSv1.2" connections and everything from Chrome to IE still uses "TLSv1.2". If I disable the use of "TLSv1.2" and "TLSv1.1" in IE and just leave "TLSv1.0" enabled then it will still work and negotiate "TLSv1.0". The setProtocols() method doesn't seem to do anything!?!
If I got this working then I was going to modify the list of Ciphers using setCipherSuites().
You can tweak it by updating jre/lib/security/java.security file. Look for an entry like below and tweak.
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.2, RC4, MD5withRSA, DH keySize < 768, \
EC keySize < 224
i found some tutorial to handle with https server and a https client. i created some keystore and it works fine. But i have some question which is not clear from the tutorial.
this is my https-server
public class HTTPSServer {
private int port = 9999;
private boolean isServerDone = false;
public static void main(String[] args) {
HTTPSServer server = new HTTPSServer();
server.run();
}
HTTPSServer() {
}
HTTPSServer(int port) {
this.port = port;
}
// Create the and initialize the SSLContext
private SSLContext createSSLContext() {
try {
//Returns keystore object in definied type, here jks
KeyStore keyStore = KeyStore.getInstance("JKS");
//loads the keystore from givin input stream, and the password to unclock jks
keyStore.load(new FileInputStream("x509-ca.jks"), "password".toCharArray());
// Create key manager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, "password".toCharArray());
KeyManager[] km = keyManagerFactory.getKeyManagers();
// Create trust manager
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
TrustManager[] tm = trustManagerFactory.getTrustManagers();
// opens a secure socket with definied protocol
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
//System.out.println(keyStore.getCertificate("root").getPublicKey());
//System.out.println(keyStore.isKeyEntry("root"));
sslContext.init(km, tm, null);
return sslContext;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
// Start to run the server
public void run() {
SSLContext sslContext = this.createSSLContext();
try {
// Create server socket factory
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
// Create server socket
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(this.port);
System.out.println("SSL server started");
while (!isServerDone) {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
// Start the server thread
new ServerThread(sslSocket).start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// Thread handling the socket from client
static class ServerThread extends Thread {
private SSLSocket sslSocket = null;
ServerThread(SSLSocket sslSocket) {
this.sslSocket = sslSocket;
}
public void run() {
sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
//System.out.println("HIER: " + sslSocket.getHandshakeSession());
//Klappt nicht, auch nicht, wenn der Client diese Zeile ebenfalls besitzt
//sslSocket.setEnabledCipherSuites(new String[]{"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"});
try {
// Start handshake
sslSocket.startHandshake();
// Get session after the connection is established
SSLSession sslSession = sslSocket.getSession();
System.out.println(sslSession.getPeerHost());
System.out.println(sslSession.getLocalCertificates());
System.out.println("\tProtocol : " + sslSession.getProtocol());
System.out.println("\tCipher suite : " + sslSession.getCipherSuite());
System.out.println("\tSession context : " + sslSession.getSessionContext());
//System.out.println("\tPeer pricipal of peer : " + sslSession.getPeerPrincipal());
// Start handling application content
InputStream inputStream = sslSocket.getInputStream();
OutputStream outputStream = sslSocket.getOutputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(outputStream));
String line = null;
String[] suites = sslSocket.getSupportedCipherSuites();
for (int i = 0; i < suites.length; i++) {
//System.out.println(suites[i]);
//System.out.println(sslSession.getCipherSuite());
}
while ((line = bufferedReader.readLine()) != null) {
System.out.println("Inut : " + line);
if (line.trim().isEmpty()) {
break;
}
}
// Write data
printWriter.print("HTTP/1.1 200\r\n");
printWriter.flush();
sslSocket.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
And this is my output:
SSL server started
127.0.0.1
null
Protocol : TLSv1.2
Cipher suite : TLS_DH_anon_WITH_AES_128_GCM_SHA256
Session context : sun.security.ssl.SSLSessionContextImpl#781df1a4
I want to know, why the line
System.out.println(sslSession.getLocalCertificates());
prints out "null"?
Thank you a lot, Mira
From the documentation:
Certificate[] getLocalCertificates()
Returns the certificate(s) that were sent to the peer during handshaking.
Note: This method is useful only when using certificate-based cipher suites.
When multiple certificates are available for use in a handshake, the implementation chooses what it considers the "best" certificate chain available, and transmits that to the other side. This method allows the caller to know which certificate chain was actually used.
Returns:
an ordered array of certificates, with the local certificate first followed by any certificate authorities. If no certificates were sent, then null is returned.
The part we care about is "Returns the certificate(s) that were sent to the peer during handshaking.", and "This method is useful only when using certificate-based cipher suites.".
Given that it is returning null, we can assume you are not sending any certificates to the client. But it's also HTTPS, so what gives? Well, it looks like you're using TLS_DH_anon_WITH_AES_128_GCM_SHA256, which is, as the name suggests, anonymous. As per the OpenSSL Wiki:
Anonymous Diffie-Hellman uses Diffie-Hellman, but without authentication. Because the keys used in the exchange are not authenticated, the protocol is susceptible to Man-in-the-Middle attacks. Note: if you use this scheme, a call to SSL_get_peer_certificate will return NULL because you have selected an anonymous protocol. This is the only time SSL_get_peer_certificate is allowed to return NULL under normal circumstances.
While this is applicable to OpenSSL, it would appear to be the same in Java - that is, you're not using a certificate-based cipher. Someone with more knowledge of TLS would need to jump in, but it looks like AES keys are generated, and they're sent to the client, but the client has no assurance those keys came from you, whereas normally you would generate the keys, and then sign / encrypt (not 100% sure) those keys with an RSA key to prove they came from you.
To fix this, I believe you would need to select a different cipher suite, e.g. TLS_RSA_WITH_AES_128_GCM_SHA256. I'm not 100% sure how you would do this, but that would appear to be the solution.
sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
You are enabling all the anonymous and low-grade cipher suites, so you are allowing the server not to send a certificate, so it doesn't send one, so it doesn't give you one in getLocalCertificates().
Remove this line.
I have an android app which is listening for socket connections and can read httpheaders (send by a browser(works all good!)). Now I wont to switch to SSL sockets but I can't get it done.
things I got working:
Keystore
ServerSocketFactory
things I not got working (and where I need help):
Client accept part
code:
public void run() {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(service.getBaseContext().getResources().openRawResource(R.raw.keystore),"password".toCharArray());
ServerSocketFactory socketFactory = SSLServerSocketFactory
.getDefault();
SSLServerSocket mServerSocket = (SSLServerSocket) socketFactory
.createServerSocket(8080);
while (!mServerSocket.isClosed()) {
mServerSocket.setEnabledCipherSuites(mServerSocket.getSupportedCipherSuites());
mServerSocket.setEnabledProtocols(mServerSocket.getSupportedProtocols());
System.out.println("waiting");
SSLSocket client = (SSLSocket) mServerSocket.accept();
client.addHandshakeCompletedListener(new HandshakeCompletedListener(){
public void handshakeCompleted(HandshakeCompletedEvent arg0) {
System.out.println("handshakeCompleted");
}
});
client.startHandshake(); //MultiThreadWebServer.java:136
client.getOutputStream().flush();
client.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Exception:
11-29 11:15:01.046: W/System.err(29941): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x4fec3da8: Failure in SSL library, usually a protocol error
11-29 11:15:01.046: W/System.err(29941): error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher (external/openssl/ssl/s3_srvr.c:1365 0x41b1e7f8:0x00000000)
11-29 11:15:01.046: W/System.err(29941): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:436)
11-29 11:15:01.046: W/System.err(29941): at at.aichinger.mario.aws.MultiThreadWebServer.run(MultiThreadWebServer.java:136)
to connect to the server I use google cheome and access "https://192.168.0.25:8080" if I do so the Exception gets throwen.
Code in line MultiThreadWebServer.java:136:
client.startHandshake();
First of all, these two lines do not make any sense. If you want to restrict supported cipher suites and protocols, define them specifically. But you have to be careful about that not all cipher suites are supported by browsers.
mServerSocket.setEnabledCipherSuites(mServerSocket.getSupportedCipherSuites());
mServerSocket.setEnabledProtocols(mServerSocket.getSupportedProtocols());
The problem in your code is that you are not using your keystore. Try this:
public void run() {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(service.getBaseContext().getResources().openRawResource(R.raw.keystore),
"password".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "password".toCharArray());
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
ServerSocketFactory socketFactory = sslContext.getServerSocketFactory();
SSLServerSocket mServerSocket = (SSLServerSocket) socketFactory.createServerSocket(8080);
while (!mServerSocket.isClosed()) {
System.out.println("waiting");
SSLSocket client = (SSLSocket) mServerSocket.accept();
client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
public void handshakeCompleted(HandshakeCompletedEvent arg0) {
System.out.println("handshakeCompleted");
}
});
client.startHandshake(); // MultiThreadWebServer.java:136
client.getOutputStream().flush();
client.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Instead of using keystore as default type, always define the type of keystore which you will use in your application. Otherwise There may be the chance where keystore mismatch will happen between server and client.
I'm trying to get an application running on top of Tomcat 6 to connect to an LDAP server over SSL.
I imported certificate of the server to keystore using:
C:\Program Files\Java\jdk1.6.0_32\jre\lib\security>keytool -importcert -trustcacerts -file mycert -alias ca_alias -keystore "c:\Program Files\Java\jdk1.6.0_32\jre\lib\security\cacerts"
When I start Tomcat with SSL debugging turned on, according to logs Tomcat is using the correct certificate file:
trustStore is: C:\Program Files\Java\jdk1.6.0_32\jre\lib\security\cacerts
However, Tomcat does not add the cert I just imported - all other certs in the cacerts file are printed to the log - and connection fails:
handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Restarting Tomcat does not help. I have verified with keytool -list command that the new cert indeed exists on the file.
Why Tomcat keeps on ignoring my new cert?
EDIT:
Seems that the issue was caused by Windows 7 VirtualStore. Keytool created a new copy of the cacert file, and Tomcat used the original file.
JVM needs restart after importing certs to the keystore.
Check to see whether there is a key with the same CN information but a different alias.
I have had similar problems before when I tried to import a newer version of a certificate but left the older version in the keystore. My Java programs would simply find the first matching CN key in the keystore (which was the old expired one) and try to use that, even though there was a newer one which also matched the CN.
Also ensure that the authenticating Root certificate (and Intermediate certificate if applicable) exist in the keystore. If you're authenticating against one of the major security providers such as Verisign or Globalsign, they will usually provide you with the root and intermediate certificates. If these certificates exist in the keystore already, ensure they are still in validity. You need to have all the certificates from your personal certificate all the way down the authentication chain to the root, existing in your keystore, so that it understands how to validate your credentials.
What you described is exactly what I´ve been getting when using cmd.exe and a regular user although member of administrative group on a Windows Server. You have to start cmd.exe in administration mode to apply the changes in to cacerts files. At least on the Win2k8 OS´s.
If you do not do this carets will show you in the keytool.exe -list view the newly added certs but Tomcat won´t see them. Not sure why so. But when you do add it with cmd.exe started as Administrator Tomcat is fine with the newly added certs.
You can also use Djavax.net.debug="ssl,handshake" to see what Tomcat reads from cacerts file.
In my case I looked through so many things before I figured out what was wrong... I added the certificate to different keystores, I added all certificates in the chain (which is pointless btw), I downloaded the cert again for my own sanity and checked the serial number, and even inspected the downloaded cert to make sure it had all the correct information.
I ended up writing a TLS verifying client app in order to debug the issue. Not only did the remote server I was connecting to support only TLS 1.2 (disabled by default in my version of Java 7), the server also supported none of the ciphers that were enabled in my client. It turns out Java 7 had fewer than half of its supported ciphers enabled, many of them being really insecure and some of the most secure ones were disabled.
After some cross-checking, I came up with the following ordered list of TLS 1.2-supported secure ciphers:
new String[] {
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
"TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256",
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",
"TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256",
"TLS_DHE_RSA_WITH_AES_256_CCM",
"TLS_DHE_RSA_WITH_AES_128_CCM",
"TLS_DHE_PSK_WITH_AES_256_CCM",
"TLS_DHE_PSK_WITH_AES_128_CCM",
"TLS_CHACHA20_POLY1305_SHA256",
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_AES_128_CCM_SHA256"
}
If there are any crypto experts around, feel free to update this list. I used Qualys SSL Labs, this Information Security SE answer, and IANA as my sources.
For those who want a sample of the source code I used, see below. I was using Apache Commons HttpClient 3.0, so you'll probably need to download the following binaries:
https://archive.apache.org/dist/httpcomponents/commons-httpclient/3.0/binary/commons-httpclient-3.0.1.zip
https://archive.apache.org/dist/commons/logging/binaries/commons-logging-1.0.4.zip
https://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.3.zip
https://archive.apache.org/dist/commons/lang/binaries/commons-lang-2.6-bin.zip
TLS12SocketFactory.java
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.*;
import org.apache.commons.lang.StringUtils;
public class TLS12SocketFactory implements SecureProtocolSocketFactory {
private final SecureProtocolSocketFactory base;
public TLS12SocketFactory()
{
this.base = (SecureProtocolSocketFactory)Protocol.getProtocol("https").getSocketFactory();
}
private Socket acceptOnlyTLS12(Socket socket)
{
if(socket instanceof javax.net.ssl.SSLSocket) {
final javax.net.ssl.SSLSocket s = (javax.net.ssl.SSLSocket)socket;
// Set TLS 1.2
s.setEnabledProtocols(new String[]{ "TLSv1.2" });
// Using recommended ciphers from https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4
List<String> recommended = new ArrayList(Arrays.asList(new String[]{ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256", "TLS_DHE_RSA_WITH_AES_256_CCM", "TLS_DHE_RSA_WITH_AES_128_CCM", "TLS_DHE_PSK_WITH_AES_256_CCM", "TLS_DHE_PSK_WITH_AES_128_CCM", "TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256", "TLS_AES_128_CCM_SHA256" }));
recommended.retainAll(Arrays.asList(s.getSupportedCipherSuites()));
if(recommended.size() == 0) {
System.err.println("No supported modern ciphers. Update crypto policy or install JCE Unlimited Strength Jurisdiction Policy files." + System.lineSeparator());
} else if(recommended.size() < 3) {
System.out.println("Few supported modern ciphers. It's recommended to update crypto policy or install JCE Unlimited Strength Jurisdiction Policy files." + System.lineSeparator());
}
s.setEnabledCipherSuites(recommended.toArray(new String[0]));
// Log matched cipher and cert
s.addHandshakeCompletedListener(new javax.net.ssl.HandshakeCompletedListener() {
#Override
public void handshakeCompleted(javax.net.ssl.HandshakeCompletedEvent hce) {
String print = s.getInetAddress().getHostName() + System.lineSeparator() + hce.getCipherSuite() + System.lineSeparator();
try {
for(java.security.cert.Certificate cert : hce.getPeerCertificates()) {
List<String> certStrings = Arrays.asList(cert.toString().split("\r?\n"));
for(int line = 0; line < certStrings.size(); line++) {
if(certStrings.get(line).startsWith("Certificate Extensions:")) {
print += System.lineSeparator() + StringUtils.join(certStrings.subList(2, line-1), System.lineSeparator()) + System.lineSeparator();
break;
}
}
}
} catch (javax.net.ssl.SSLPeerUnverifiedException ex) {
print += "Non-certificate based cipher used" + System.lineSeparator();
}
System.out.println(print);
}
});
}
return socket;
}
#Override
public Socket createSocket(String host, int port) throws IOException
{
return acceptOnlyTLS12(base.createSocket(host, port));
}
#Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException
{
return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort));
}
#Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException
{
return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort, params));
}
#Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
{
return acceptOnlyTLS12(base.createSocket(socket, host, port, autoClose));
}
}
Main.java
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpClientParams;
public class Main {
public static void main(String[] args) {
List<java.net.URI> locations = new ArrayList<>();
for(String arg : args) {
java.net.URI location = java.net.URI.create(arg);
if(location.isAbsolute() && location.getScheme().equals("https")) {
locations.add(location);
} else {
System.out.println("Skipping invalid URL: " + arg);
}
}
System.out.println("Connecting to URL's");
System.out.println();
System.out.println("-------------------------");
TLS12SocketFactory tls12factory = new TLS12SocketFactory();
Protocol.registerProtocol("httpss", new Protocol("httpss", tls12factory, 443));
for(java.net.URI location : locations) {
System.out.println();
try {
// Form request
String tls12url = location.toString().replaceFirst("^https:", "httpss:");
HttpMethod method = new HeadMethod(tls12url);
// Send request
HttpClientParams params = new HttpClientParams();
params.setParameter(HttpClientParams.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);
new HttpClient(params).executeMethod(method);
method.setFollowRedirects(true);
// Print response
System.out.println(location.toString());
System.out.println(method.getStatusLine().toString());
} catch (javax.net.ssl.SSLHandshakeException ex) {
System.out.println("There was an error making a secure connection to " + location.getHost());
ex.printStackTrace(System.out);
} catch (HttpException ex) {
System.out.println("There was an error with the external webpage");
ex.printStackTrace(System.out);
} catch (Exception ex) {
System.out.println("Could not complete request");
ex.printStackTrace(System.out);
}
}
System.out.println();
System.out.println("-------------------------");
System.out.println();
try {
// Load supported SSL Ciphers
System.out.println("Supported ciphers");
System.out.println();
System.out.println("-------------------------");
System.out.println();
javax.net.ssl.SSLSocket socket = (javax.net.ssl.SSLSocket)tls12factory.createSocket("www.google.com", 443);
for(String cipher : socket.getSupportedCipherSuites()) {
System.out.println(cipher);
}
System.out.println();
System.out.println("-------------------------");
System.out.println();
// Load enabled SSL Ciphers
System.out.println("Enabled ciphers");
System.out.println();
System.out.println("-------------------------");
System.out.println();
for(String cipher : socket.getEnabledCipherSuites()) {
System.out.println(cipher);
}
System.out.println();
System.out.println("-------------------------");
System.out.println();
// Load the JDK's cacerts keystore file
String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar);
System.out.println("Loading keystore");
System.out.println(filename);
System.out.println();
System.out.println("-------------------------");
System.out.println();
FileInputStream is = new FileInputStream(filename);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
String password = "changeit";
keystore.load(is, password.toCharArray());
// This class retrieves the most-trusted CAs from the keystore
PKIXParameters params = new PKIXParameters(keystore);
// Get the set of trust anchors, which contain the most-trusted CA certificates
for (TrustAnchor ta : params.getTrustAnchors()) {
// Print certificate
System.out.println(ta.getTrustedCert());
}
} catch (CertificateException | KeyStoreException | NoSuchAlgorithmException | InvalidAlgorithmParameterException | IOException ex) {
System.out.println("Could not load keystore");
ex.printStackTrace(System.out);
}
}
}