Reputation: 141
I installed apache server locally on my computer and running . I started with SSL server certificate for server authentication. To do this i added the server keystore path to the server.xml file of the tomcat and server certificate to truststore of SSL context in android app.Its working perfectly fine.
Now I need to configure the same for client authentication. For that I created a client keystore and stored that keystore in the resources/raw folder of android app and put that in keystore of the android app.
I created keystore for server and client using the below commands .
keytool -genkey -alias server -keyalg RSA -keystore server.jks
keytool -genkey -alias client -keyalg RSA -keystore client.jks
keytool -export -file server.cert -keystore server.jks -storepass password -alias server
keytool -export -file client.cert -keystore client.jks -storepass password -alias client
So i created 2 keystores , one for client and other for server , client.jks and server.jks . And i have client.cer and server.cer certificates exported from the corresponding keystore.
Client (Android application code) used to configure the SSL context . I have stored client.jks and server.cer files in the res/raw folder and referring that in the below code.
public HttpClient myHttpsClient() {
HttpClient client = null;
char[] passphrase = "password".toCharArray();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertificateFactory clientcf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.server);
InputStream clientcert = context.getResources().openRawResource(R.raw.client);
Certificate ca;
Certificate clientca;
try {
clientca = clientcf.generateCertificate(clientcert);
ca = cf.generateCertificate(caInput);
System.out.println("ca="+ ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
clientcert.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStoreclient = KeyStore.getInstance(keyStoreType);
keyStoreclient.load(null, null);
keyStoreclient.setCertificateEntry("ca", clientca);
// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
kmf.init(keyStoreclient,passphrase);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
MySSLSocketFactory socketFactory = new MySSLSocketFactory(context);//,new BrowserCompatHostnameVerifier());
client = createHttps(socketFactory);
} catch (Exception e) {
e.printStackTrace();
}
return client;
Now the server is configured as below .
<Connector SSLEnabled="true" acceptCount="100" clientAuth="false" truststoreFile="/Users/prabhuraj/client.cer"
truststorePass="password" disableUploadTimeout="true" enableLookups="false" maxThreads="25"
port="8443" keystoreFile="/Users/prabhuraj/server.jks" keystorePass="password"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS" />
After configuring as above. SSL handshake is failing . Can someone please let me know whether i am configuring wrongly? Thanks in advance.
Upvotes: 0
Views: 2412
Reputation: 2769
You didnt use your KeyManagerFactory
to init SSLContext
,
change:
context.init(null, tmf.getTrustManagers(), null);
to
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
However, your certificate used for client auth, will need it's private key. Look at this post for explaination: https://stackoverflow.com/a/11199270/2762154
Upvotes: 1