This Blog will assist you to configure 2 way SSL in Apache 2 web server which I have hosted in Ubuntu 10.04(LUCID) . I have also tested 2 way SSL with a Java Client . The code can found here .
The certificates I have generated are self-signed .
Introduction:
Now a days B2B integration requires integrity and confidentiality of the data transferred. That is where SSL ( Secure Sockets Layer ) comes into picture. To achieve integrity and confidentiality of the data you need to enable SSL in your web server .
One-way SSL authentication allows a SSL client to confirm an identity of SSL server. However, SSL server cannot confirm an identity of SSL client. This kind of SSL authentication is used by HTTPS protocol. The SSL client authentication is done on a “application layer” of OSI model by the client entering an authentication credentials such as username and password or by using a grid card.
Two-way SSL authentication also known as mutual SSL authentication allows SSL client to confirm an identity of SSL server and SSL server can also confirm an identity of the SSL client. This type of authentication is called client authentication because SSL client shows its identity to SSL server with a use of the client certificate. Client authentication with a certificate can add yet another layer of security or even completely replace authentication method such us user name and password.
Generate Self-Signed certificate with Open SSL
As first step I have created a directory where I have generated all server and client keys and certificates.
Next we need to generate self-signed certificate CA. Once prompted for a set of values we can provide dummy values but relevant to your organisation. I have provided a screen shot below .
In your current directory a file “ca.key” with private key of certificate authority (CA) and ca.cer with its self-signed certificate.
Next step we need to generate private SSL key for the server:
Next we would generate Certificate Signing Request in PKCS#10 format.Once the command is entered we will asked for a set of values . I have provided a screen shot below .
Next we will issue server certificate with serial number 100 with self-signed certificate authority:
Currently if you list down your files in current directory you should following files generated:
New file server.key contains server's private key and file server.cer is a certificate itself.
Next for 2 way SSL Generete private key for SSL client:
For client as we need to generate Certificate Signing Request:
With the self-signed Certificate Authority that we have generated ,we will issue a client certificate with serial number 101:
Next we will save client's private key and certificate in a PKCS#12 format. This certificate will be secured by a password and this password will be used in the following sections to import the certificate into HTTPS client. I have kept the password as "changeit" .
Configure 2 Way SSL in Apache 2
First thing is copying all the server certificates , keys i.e ca.cer, server.cer, server.key files to "ssl" directory under apache2( /etc/apache2/ssl ).
Once copying is done open "default-ssl" file under "/etc/apache2/sites-available". Search for "SSLCertificateFile" . If it is commented , then uncomment and add the location of the "server.cer" file .
Do the same for "SSLCertificateKeyFile" as above.
Next search for "SSLVerifyClient" in the same file . Once found, replace with the below configuration.
Then save the file and restart apache web server.
Test 2 Way SSL
We can test 2 Way SSL with following ways :
The certificates I have generated are self-signed .
Introduction:
Now a days B2B integration requires integrity and confidentiality of the data transferred. That is where SSL ( Secure Sockets Layer ) comes into picture. To achieve integrity and confidentiality of the data you need to enable SSL in your web server .
One-way SSL authentication allows a SSL client to confirm an identity of SSL server. However, SSL server cannot confirm an identity of SSL client. This kind of SSL authentication is used by HTTPS protocol. The SSL client authentication is done on a “application layer” of OSI model by the client entering an authentication credentials such as username and password or by using a grid card.
Two-way SSL authentication also known as mutual SSL authentication allows SSL client to confirm an identity of SSL server and SSL server can also confirm an identity of the SSL client. This type of authentication is called client authentication because SSL client shows its identity to SSL server with a use of the client certificate. Client authentication with a certificate can add yet another layer of security or even completely replace authentication method such us user name and password.
Generate Self-Signed certificate with Open SSL
As first step I have created a directory where I have generated all server and client keys and certificates.
prasenjit@prasenjit-desktop:~$ mkdir ssl_keys
Next we need to generate self-signed certificate CA. Once prompted for a set of values we can provide dummy values but relevant to your organisation. I have provided a screen shot below .
openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -outform PEM -out ca.cer
In your current directory a file “ca.key” with private key of certificate authority (CA) and ca.cer with its self-signed certificate.
Next step we need to generate private SSL key for the server:
openssl genrsa -out server.key 2048
Next we would generate Certificate Signing Request in PKCS#10 format.Once the command is entered we will asked for a set of values . I have provided a screen shot below .
openssl req -new -key server.key -out server.req
Next we will issue server certificate with serial number 100 with self-signed certificate authority:
openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extensions server -days 365 -outform PEM -out server.cer
Currently if you list down your files in current directory you should following files generated:
ca.key
ca.cer
server.key
server.req
server.cer
New file server.key contains server's private key and file server.cer is a certificate itself.
Next for 2 way SSL Generete private key for SSL client:
openssl genrsa -out client.key 2048
For client as we need to generate Certificate Signing Request:
openssl req -new -key client.key -out client.req
With the self-signed Certificate Authority that we have generated ,we will issue a client certificate with serial number 101:
openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key -set_serial 101 -extensions client -days 365 -outform PEM -out client.cer
Next we will save client's private key and certificate in a PKCS#12 format. This certificate will be secured by a password and this password will be used in the following sections to import the certificate into HTTPS client. I have kept the password as "changeit" .
openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12
Configure 2 Way SSL in Apache 2
First thing is copying all the server certificates , keys i.e ca.cer, server.cer, server.key files to "ssl" directory under apache2( /etc/apache2/ssl ).
Once copying is done open "default-ssl" file under "/etc/apache2/sites-available". Search for "SSLCertificateFile" . If it is commented , then uncomment and add the location of the "server.cer" file .
Do the same for "SSLCertificateKeyFile" as above.
Next search for "SSLVerifyClient" in the same file . Once found, replace with the below configuration.
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /etc/apache2/ssl/ca.cer
Then save the file and restart apache web server.
/etc/init.d/apache2 restart
Test 2 Way SSL
We can test 2 Way SSL with following ways :
- Web Browser . It is very easy if you have the client keystore file ( client.p12 ) with PKCS#12 format , just import the file in your browser and you will be able to launch the apache 2 default web page( https://localhost/ ).
- Java Https Client : Most B2B applications will use HTTPS clients to connect 2 way ssl enabled server . I have written a sample Java client which connects to my 2 Way ssl enabled server . To test the client we should have the following :
- Copy the client keystore file ( client.p12 ) from server to a local directory( Lets say in my case I have downloaded to 'D:\ubuntu_apache_keys\apacheKeys' ).
- Generate trustStore file using 'keytool' command and copy the trustStore from server to a local directory. ( Lets say in my case I have downloaded to 'D:\ubuntu_apache_keys\apacheKeys' ).
keytool -import -alias myapacheserver -file ca.cer -storepass changeit -keystore myapacheserver.keystore
Once the command is entered , it will ask as if we trust the certificate . We should answer with "yes" or "no". I have added yes to add it in my trustore. Below is a screenshot.
Replace the IP address in the code with your server's IP address.
package com.prasenjit.samples;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
public class TwoWaySSLClient {
public static void main(String[] args) {
SSLSocketFactory sslsocketfactory =(SSLSocketFactory) SSLSocketFactory.getDefault();
try {
URL url = new URL("https://192.168.0.102/");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
conn.setSSLSocketFactory(sslsocketfactory);
InputStream inputstream = conn.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String string = null;
while ((string = bufferedreader.readLine()) != null) {
System.out.println("Received " + string);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run the above code with the below arguments.
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=D:\\ubuntu_apache_keys\\apacheKeys\\client.p12
-Djavax.net.ssl.trustStore=D:\\ubuntu_apache_keys\\apacheKeys\\myapacheserver.keystore
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStorePassword=changeit
If you have followed the above steps you should be able to connect 2 Way SSL enabled Apache2 web server without any error or exceptions. You can also trace the ssl handshake logs using the above param "-Djavax.net.debug=ssl" . I will soon add the Java src file to my GitHub .
Please add valuable feedback/comments about this post .
Thanks.
References:
The below articles and websites are used for reference . Please do visit for more explanation.
- http://linuxconfig.org/apache-web-server-ssl-authentication
- http://httpd.apache.org/docs/2.2/ssl/ssl_howto.html
- http://emo.sourceforge.net/cert-login-howto.html