Sunday, June 6, 2010

Creating Trust Store and Identity Key Store for 2 Way SSL Connectivity using Java

In my earlier article, I have highlighted how to connect a URL using 2 way SSL connectivity. While connecting to that URL, we have used two certificate key stores; one is trust store and identity key stores.

However, this article will tell you those key stores using open ssl commands and few java codes.

Let me give you the background before going to the step by step process to create the key stores.

There are generally two kinds of certificates: Client Certificate and Server Certificate.
 
Client certificate is usually installed on a client's browser and provides user identity to the server at the other end. The client certificate is also having a public key and a certificate to the server. This public key is used by the server to encrypt any data exchange between these two parties. Server certificate is installed on the server side and provides server identity, certificate, and public key information to clients that try to establish a connection. The certificate and public key are used for handshaking and further data encryption between client and server.
 
The identity key store is containing the identity of the client certificate, intermediate, root certificate and the private key associated with it. The trust store is containing only the root certificate, which is generally common to the server and client certificate.


First let me go through the steps how to export the client certificate onto your local drive.

 




Now, you have the client certificate in pfx format in your local drive.
Step 1: Creating the Identity Key store:
a. Convert the pfx certificate onto the pem format


Using below open ssl command, you need to convert the pfx certificate onto the pem format

openssl pkcs12 -in client.pfx -out client.pem –nodes



b. The resulting file will have all the certificates in the following order:


Private key, Identity certificate, Root certificate, Intermediate certificate

c. From the client.pem file, copy the private key and paste it in different file, say my_key_pk.pem. It is very easy to identify the private key as it is wrapped with in the following two headers:


-----BEGIN RSA PRIVATE KEY-----



-----END RSA PRIVATE KEY-----



d. From the client.pem file, create a new file (my_key_crt.pem) with the certificates reordered The order is important, otherwise the hosting server will not recognize the certificates:




Identity certificate, Intermediate certificate, Root certificate, Private Key



Now the my_key_crt.pem can be directly used by a Java client to invoking web services over SSL.

e. Now you need to create identity key store while importing private key either by the following two way

1. Using Weblogic Utility:




java utils.ImportPrivateKey -keystore my_key_identity.jks -storepass passw0rd -storetype JKS -keypass passw0rd -alias my_key_crt -certfile my_key_crt.pem -keyfile my_key_pk.pem



OR


1. Convert the Convert both, the key and the certificate into DER format using openssl




openssl pkcs8 -topk8 -nocrypt -in my_key_pk.pem -inform PEM -out my_key_pk.der -outform DER



openssl x509 -in my_key_crt.pem -inform PEM -out my_key_crt.der -outform DER


2. Using the following Java code import the private key and the certificate on to the identity keystore.




import java.security.*;

import java.io.IOException;

import java.io.InputStream;

import java.io.FileInputStream;

import java.io.DataInputStream;

import java.io.ByteArrayInputStream;

import java.io.FileOutputStream;

import java.security.spec.*;

import java.security.cert.Certificate;

import java.security.cert.CertificateFactory;

import java.util.Collection;

import java.util.Iterator;





public class ImportKey {



private static InputStream fullStream ( String fname ) throws IOException {

FileInputStream fis = new FileInputStream(fname);

DataInputStream dis = new DataInputStream(fis);

byte[] bytes = new byte[dis.available()];

dis.readFully(bytes);

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

return bais;

}





public static void main ( String args[]) {





String keypass = "passw0rd";



String defaultalias = "importkey";



String keystorename = "./my_key_identity.jks";

String keyfile = "./my_key_pk.der";

String certfile = "./my_key_crt.der";



try {



KeyStore ks = KeyStore.getInstance("JKS", "SUN");

ks.load( null , keypass.toCharArray());

System.out.println("Using keystore-file : "+keystorename);

ks.store(new FileOutputStream ( keystorename ), keypass.toCharArray());

ks.load(new FileInputStream ( keystorename ), keypass.toCharArray());



InputStream fl = fullStream (keyfile);

byte[] key = new byte[fl.available()];

KeyFactory kf = KeyFactory.getInstance("RSA");

fl.read ( key, 0, fl.available() );

fl.close();

PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );

PrivateKey ff = kf.generatePrivate (keysp);





CertificateFactory cf = CertificateFactory.getInstance("X.509");

InputStream certstream = fullStream (certfile);



Collection c = cf.generateCertificates(certstream) ;

Certificate[] certs = new Certificate[c.toArray().length];



if (c.size() == 1) {

certstream = fullStream (certfile);

System.out.println("One certificate, no chain.");

Certificate cert = cf.generateCertificate(certstream) ;

certs[0] = cert;

} else {

System.out.println("Certificate chain length: "+c.size());

certs = (Certificate[])c.toArray();

}





ks.setKeyEntry(defaultalias, ff, keypass.toCharArray(), certs );

System.out.println ("Key and certificate stored.");

System.out.println ("Alias:"+defaultalias+" Password:"+keypass);

ks.store(new FileOutputStream ( keystorename ), keypass.toCharArray());

} catch (Exception ex) {

ex.printStackTrace();

}

}



}


Step 2: Creating the Trust Java Key Store


Open the my_key_crt.pem file in a text editor, copy the root certificate and paste it to a new file, say my_key_root.pem. You can easily find the root certificate since its issuer and subject headers must be same.

Use the Java key tool utility and import the above my_key_root.pem file to a JKS file:

keytool -import -trustcacerts -file my_key_root.pem -alias my_key_root -keystore my_key_trust.jks -storepass passw0rd

 
 
Now, you have trust store [my_key_trust.jks] and identity key store [my_key_identity.jks] which you have use to connect to a 2 way SSL URL.


Hope you all will find it useful.

Saturday, January 30, 2010

List out the system properties values - Java Source Code

import java.util.Properties;
public class ListProperties {

/** Creates a new instance of ListProperties */
public ListProperties() {
}

private void getListProperties() {
Properties props = System.getProperties();
props.list(System.out);
}

public static void main(String[] args) {
ListProperties listProps = new ListProperties();
listProps.getListProperties();
}
}

http://java.sun.com/javase/6/docs/api/java/util/Properties.html

Output
-- listing properties --
java.runtime.name=Java(TM) 2 Runtime Environment, Stand...
sun.boot.library.path=C:\Program Files\Java\jdk1.5.0_06\jre...
java.vm.version=1.5.0_06-b05
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
user.country=GB
sun.os.patch.level=Service Pack 3
java.vm.specification.name=Java Virtual Machine Specification
user.dir=E:\JavaProjects\JavaTest
java.runtime.version=1.5.0_06-b05
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Program Files\Java\jdk1.5.0_06\jre...
os.arch=x86
java.io.tmpdir=C:\DOCUME~1\SC0031~1\LOCALS~1\Temp\
line.separator=

java.vm.specification.vendor=Sun Microsystems Inc.
user.variant=
os.name=Windows XP
sun.jnu.encoding=Cp1252
java.library.path=C:\Program Files\Java\jdk1.5.0_06\jre...
java.specification.name=Java Platform API Specification
java.class.version=49.0
sun.management.compiler=HotSpot Client Compiler
os.version=5.1
user.home=C:\Documents and Settings\sc0031744
user.timezone=
java.security.policy=applet.policy
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=Cp1252
java.specification.version=1.5
user.name=sc0031744
java.class.path=C:\Program Files\netbeans-5.0\platfor...
java.vm.specification.version=1.0
sun.arch.data.model=32
java.home=C:\Program Files\Java\jdk1.5.0_06\jre
java.specification.vendor=Sun Microsystems Inc.
user.language=en
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode, sharing
java.version=1.5.0_06
java.ext.dirs=C:\Program Files\Java\jdk1.5.0_06\jre...
sun.boot.class.path=C:\Program Files\Java\jdk1.5.0_06\jre...
java.vendor=Sun Microsystems Inc.
file.separator=\
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport...
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=

Thursday, January 7, 2010

Include a tag with an attribute in XML – Java Source Code

In my previous article, I have shown you how the tags can be inserted to a XML file using Java Source Code. The below example will show you to do the same thing with an attribute added to it.




The below simple source code will append a node [address] before a specific node [telephone] and under specific parent node [employee] of a specific XML. Address node will have an attribute type [type].












import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Attr;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;



/**
*
* @author Snehanshu Chatterjee
*/
public class AppendChild {

/** Creates a new instance of AppendChild */
public AppendChild() {
}

private void appendChildIntoXML(){

}

public static void main(String[] args) {
try{
File xmlDocument = new File("./Company.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlDocument);
insertNode(document,xmlDocument);
}catch(Exception e){
e.printStackTrace();
}
}


private static void insertNode(Document doc,File fileDoc){
Node parentNode = doc.getParentNode();
Node employee = doc.getElementsByTagName("employee").item(0);
Node telephone = doc.getElementsByTagName("telephone").item(0);
Node addressNode = (Node) doc.createElement("address");

//Creating an Attribute

Attr addressNodeAttr = doc.createAttribute("type");
addressNodeAttr.setValue("homeaddress");

//Setting that attribute to the Node [address]

Element addressNodeElement = (Element)addressNode;
// The above line of code is to convert the [Node] to [Element]
addressNodeElement.setAttributeNode(addressNodeAttr);

Node newChild = employee.appendChild(addressNode);
employee.insertBefore(newChild,telephone);

try {
// create DOMSource for source XML document
Source xmlSource = new DOMSource(doc);
// create StreamResult for transformation result
Result result = new StreamResult(new FileOutputStream(fileDoc));
// create TransformerFactory
TransformerFactory transformerFactory = TransformerFactory.newInstance();
// create Transformer for transformation
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty("indent", "yes");
// transform and deliver content to client
transformer.transform(xmlSource, result);
} catch (TransformerFactoryConfigurationError factoryError) {
// handle exception creating TransformerFactory
System.err.println("Error creating " + "TransformerFactory");
factoryError.printStackTrace();
}catch (TransformerException transformerError) {
System.err.println("Error transforming document");
transformerError.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
}

}

}

Run:
set classpath=.
javac AppendChild.java
java AppendChild
pause




Tuesday, January 5, 2010

Difference between Protected and Default members - Java

The protected and default access control levels are almost identical with one critical difference. A default memeber can be accessed only if the class accessing the members belong to the same package, whereas a protected member can be accessed [only through inheritence] by a sub class even if the subclass is in a different package.

Total Pageviews