Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Convert jks keystore to pkcs12 - Here's how, but one thing puzzles me...

843811Jan 7 2006 — edited Jan 11 2006
Last week I managed to finish my first Java program (a commandline calculator: when you present it with 2 parameters they'll be used for all 4 major mathematic operations, otherwise it'll ask for the parameters) and this weekend I looked into deployment. I made a jarfile, then I made an "executable" jarfile and then I stumbled upon signing.

After I discovered the 'keytool' oddity (see other forum) I decided to rebuild my keystore. But since this would mean that I would also lose my keys I tried to use 'openssl' to look into the keystore, without any result. Then after reading up even more about this I discovered the jks and pkcs12 encoding differences and because it became quickly clear to me that Java supported both I tried to write a converter for it. It took me a few hours (I'm still a beginner when it comes to Java, slowly becoming more familiar with it) and here it is:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.*;

public class ConvertKeystore {

   static public void main( String[] args ) {

     try {
       // define 2 keystore formats
       KeyStore ks = KeyStore.getInstance("jks");
       KeyStore nks = KeyStore.getInstance("pkcs12");

       // Load the jks keystore and open the pkcs12 store
       ks.load(new FileInputStream("/home/peter/.keystore"), "password".toCharA
rray());
       nks.load(null, "changeit".toCharArray());

       // Get the private key entry and store it in the new keystore
       KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry
("mykey", new KeyStore.PasswordProtection("password".toCharArray()));
       nks.setEntry("newkey", pkEntry, new KeyStore.PasswordProtection("changeit
".toCharArray()));

       // Store the new keystore
       FileOutputStream fos = new FileOutputStream("/home/peter/new-keystore");
       nks.store(fos, "changeit".toCharArray() );
       fos.close();
     } catch (Exception e) { System.out.println(e); }
   }

} // End of class
This is all very basic ofcourse and still needs some work (as you can see it only converts 1 entry which also has to be explicitly named) but its sufficient for now. After this program has run you can convert the pkcs12 "new-store" file to a PEM keybag which will contain the private key as well as the certificate. You can do so using:
openssl pkcs12 -in new-keystore -out keybag.pem
And then you're left with a "keybag.pem" which is also in the usual PEM (ascii) format.

Now, as you can see I used "KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("mykey", new KeyStore.PasswordProtection("password".toCharArray()));" to 'filter' the result because "KeyStore.getEntry" returns a "KeyStore.Entry" while I needed a "PrivateKeyEntry". I've gone over the JDK documentation several times now but couldn't find anything to get a private keyentry directly so I finally wondered if I could "filter" it. I then noticed that the example in the KeyStore class also used this same method so I just went along with it.

Now I can't help wonder if I missed another possibility, has anyone else have another way to approach this ?
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Feb 8 2006
Added on Jan 7 2006
2 comments
1,313 views