How to do SSL connection using .pfx
key file and password in java (HTTPClient)
If you are going to use HTTPClient to extract the java understanding
TrustStore, KeyStore are very impotent.
KeyStore: Is
nothing but private key (.pfx and
its password) information that client is used to connect remote machine. Used by client.
Truststore :
Which contains trusted certificates chain. Used
by server.
Why we need these certificates while connecting from HTTP client/java?
In client server communication first client send “hello”
request. Server would replay to this with “hello” response. The response also
contains the certificate usually “singed by CA” and ask the client something
say do you trust this certificate? Then client
(java) looks for this certificate in the truststore
(certificate chain) whether this certificate can be trusted or not? If this
certificate in trust store, client send “true” to Server. Once client trust the certificate, server
allows accessing to server method. If server
method access restricted it looks for private key and its password.
This is all happens in fraction of mile seconds and this is
called a HAND-SHAKE. If anything goes wrong in handshake we get handshake
exception.
Connecting to server using httpclient is all about
configuring the right sslcontext.
Below is the abstract
java class you can use this directly by extending to your own class. This class
would create write client for you.
If you don’t have “truststore” and just need to trust all certificates
blindly use below method to create client.
getHttpClientWithoutTrustKey()
If you created trust store than use below method to get client
DefaultHttpClient getHttpClient()
In both methods it is important to understand how I am
creating keystore,truststore, and SSLContext.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | package com.my.downloaders; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.X509Certificate; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.springframework.util.Assert; /* * keytool -keystore <trustore name> -import -alias <alias name >-file certificate.cer -trustcacerts */ public abstract class AbstractHTTPSWithPrivateKeyDownloader { private static Logger logger = Logger.getLogger(AbstractHTTPSWithPrivateKeyDownloader.class.getName()); public String trustStoreKey;//="truststore location"; public String trustStorePass;//="trustostore"; public String keyStoreKey;//=”absolute path to .pfx file”; public String keyStorePassowrd;//=""; public String privatePassWord;//="it is same as keyStorePassowrd "; public void afterPropertiesSet() throws Exception { Assert.notNull(keyStorePassowrd, "keyStorePassowrd property cannot be NULL."); Assert.notNull(keyStoreKey, "keyStore property cannot be NULL."); } public abstract void doExecute() throws Exception; public void setTrustStoreKey(String trustStoreKey) { this.trustStoreKey = trustStoreKey; } public void setTrustStorePass(String trustStorePass) { this.trustStorePass = trustStorePass; } public void setKeyStoreKey(String keyStoreKey) { this.keyStoreKey = keyStoreKey; } public void setKeyStorePassowrd(String keyStorePassowrd) { this.keyStorePassowrd = keyStorePassowrd; this.privatePassWord=keyStorePassowrd; } protected DefaultHttpClient getHttpClient() throws Exception{ try { KeyStore trustStore = getTrustoStore(new File(trustStoreKey), trustStorePass); KeyStore keyStore = getKeyStore(new File(keyStoreKey), keyStorePassowrd); SSLSocketFactory socketFactory = getSSLSocketFactory( privatePassWord, trustStore, keyStore); Scheme sch = new Scheme("https", 443, socketFactory); DefaultHttpClient httpclient = new DefaultHttpClient(); httpclient.getConnectionManager().getSchemeRegistry().register(sch); return httpclient; } catch(Exception e) { logger.log(Level.WARNING, e.getMessage(), e); return getHttpClientWithoutTrustKey(); } } protected DefaultHttpClient getHttpClientWithoutTrustKey() throws Exception{ KeyStore keyStore = getKeyStore(new File(keyStoreKey), keyStorePassowrd); KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmfactory.init(keyStore, keyStorePassowrd.toCharArray()); SSLContext sslContext = SSLContext.getInstance("SSL"); // set up a TrustManager that trusts everything sslContext.init(kmfactory.getKeyManagers(), new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { logger.info("getAcceptedIssuers ============="); return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { logger.info("checkClientTrusted ============="); } public void checkServerTrusted(X509Certificate[] certs, String authType) { logger.info("checkServerTrusted ============="); } } }, new SecureRandom()); SSLSocketFactory socketFactory = new SSLSocketFactory(sslContext); Scheme sch = new Scheme("https", 443, socketFactory); DefaultHttpClient httpclient = new DefaultHttpClient(); httpclient.getConnectionManager().getSchemeRegistry().register(sch); return httpclient; } protected SSLSocketFactory getSSLSocketFactory( String privateKeyPassword, KeyStore trustStore, KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { SSLSocketFactory socketFactory = null; try { socketFactory = new SSLSocketFactory(keyStore, privateKeyPassword, trustStore); } catch (UnrecoverableKeyException ke) { logger.severe("Failed to create SSLSocketFactory, possible wrong password on client private key"); } return socketFactory; } protected static KeyStore getTrustoStore(File truststoreFile, String truststorePassword) throws Exception { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream trustStream = new FileInputStream(truststoreFile); try { logger.info("Loading server truststore from file " + truststoreFile.getPath()); trustStore.load(trustStream, truststorePassword.toCharArray()); logger.info("Truststore certificate count: " + trustStore.size()); } catch (Exception ex) { logger.severe("Failed to load truststore: " + ex.toString()); throw ex; } finally { try { trustStream.close(); } catch (Exception ignore) { } } return trustStore; } protected static KeyStore getKeyStore(File keystoreFile, String keystorePassword) throws KeyStoreException, NoSuchProviderException, FileNotFoundException { KeyStore keyStore = KeyStore.getInstance("PKCS12", "SunJSSE"); FileInputStream keyStream = new FileInputStream(keystoreFile); try { logger.info("Loading client keystore from file " + keystoreFile.getPath()); keyStore.load(keyStream, keystorePassword.toCharArray()); logger.info("Keystore certificate count: " + keyStore.size()); } catch (Exception e) { System.err.println("Failed to load keystore: " + e.toString()); logger.log(Level.SEVERE, e.getMessage(), e); } finally { try { keyStream.close(); } catch (Exception e) { logger.log(Level.WARNING, e.getMessage(), e); } } return keyStore; } } |
How to use the above class?
Create a URI and override the doExcecute() method.
public class CliendDownloader extends
AbstractHTTPSWithPrivateKeyDownloader implements Tasklet,
InitializingBean {
static {
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation","true");
}
private static Logger logger = Logger.getLogger(CliendDownloader.class.getName());
public String url;
public void setUrl(String url) {
this.url = url;
}
public void doExecute() throws Exception {
URI
targetURI = new URI(url.trim());
String
protocol = targetURI.getScheme();
if (!"https".equals(protocol)) {
logger.severe("URI does not
begin with expected protocol name");
return;
}
logger.info("URI to fetch
is "
+ targetURI.toString());
try {
if(trustStoreKey!=null && trustStorePass!=null)
{
httpclient
= getHttpClient();
}
else
{
httpclient
= getHttpClientWithoutTrustKey();
}
HttpGet
httpget = new HttpGet(targetURI);
HttpResponse
response = null;
try {
response
= httpclient.execute(httpget);
-----------
-------
}
}
How to create trust store?
If you would like to have trustore
Import the certificate from IE browser download in .cer format and run
the below command.
keytool -keystore <trustore
name> -import -alias <alias name > -file certificate.cer -trustcacerts
Thanks Santosh. Very Nice Article. It really helpful for me
ReplyDeleteProve your skills with CCA 175 certification exam. Getting through this exam is not easy. It requires hard work and hands on training on projects related or relevant to CCA 175 certification program. Get passed in CCA 175 certification exam through our intensive training and hands on experience on projects.
ReplyDeletecca 175 certification
cloudera hadoop developer certification
cca 175 spark and hadoop developer certification
hadoop developer certification
Thank you very much for this example!
ReplyDelete