Importing existing VeriSign key and certificate chain into a keystore

So, I already have a VeriSign main certificate and intermediate certificate for Videoslots.com. This certificate has already been installed in Apache and works OK.


The problem was that the external affiliate system running on Jetty, Clojure and MongoDB was using http. When affiliates were accessing their affiliate accounts to for instance pick banners for their campaigns they were being met with white rectangles instead. The browsers were blocking this non encrypted communication happening within the confines of an encrypted domain. Solution: encrypt the external affiliate system using a CA signed certificate too.

The first thing is getting the Jetty/Ring code to serve up an https server, this Sandbar article took care of showing how to do that.

The main problem now was how to create a keystore from the existing key, main certificate and intermediate certificate and I found the solution here. Specifically, the second comment by Johann Renck worked for me.

1.) I downloaded the java source code.

2.) Made the change Johann talked about on line 147.

3.) And ran the following (all files are in the same directory):

openssl pkcs8 -topk8 -nocrypt -in server.key -inform PEM -out server.der -outform DER
openssl x509 -in main_cert.crt -inform PEM -out main_cert.der -outform DER
openssl x509 -in main_intermediate.crt -inform PEM -out main_intermediate.der -outform DER
cat main_cert.der main_intermediate.der > all.der
javac *.java
java ImportKey server.der all.der

I keep forgetting the code all the time, and having to that line over and over again, here it is, fixed:

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;

/**
 * @author Joachim Karrer, Jens Carlberg
 * @version 1.1
 **/
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[]) {
        
        // change this if you want another password by default
        String keypass = "importkey";
        
        // change this if you want another alias by default
        String defaultalias = "importkey";

        // change this if you want another keystorefile by default
        String keystorename = System.getProperty("keystore");

        if (keystorename == null)
            keystorename = System.getProperty("user.home")+
                System.getProperty("file.separator")+
                "keystore.ImportKey"; // especially this ;-)


        // parsing command line input
        String keyfile = "";
        String certfile = "";
        if (args.length < 2 || args.length>3) {
            System.out.println("Usage: java comu.ImportKey keyfile certfile [alias]");
            System.exit(0);
        } else {
            keyfile = args[0];
            certfile = args[1];
            if (args.length>2)
                defaultalias = args[2];
        }

        try {
            // initializing and clearing keystore 
            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());

            // loading Key
            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);

            // loading CertificateChain
            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();
                certs = (Certificate[])c.toArray(new Certificate[0]);
            }

            // storing keystore
            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();
        }
    }

}// KeyStore

Works!

Related Posts

Tags: , , , , ,