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());
DefaultHttpClient
httpclient =null;
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