Exporting the Private Key from a JKS keystore
Java - 37 Comments » - Posted on January, 19 at 3:22 pm
A common problem faced when moving certificates and keys from tomcat to Apache web server is that keytool does not allow you to export the private key in the format that apache’s modssl module requires. Mark Foster’s post and Andrew Morrow’s post contains valuable information on how to export a key from a JKS keystore.
Here is a summary of the steps needed to export a private key
Download ExportPrivateKey.zip
Invoke
This would export the key to PKCS #8 PEM format. Now run openssl to convert it to the format apache modssl expects the file in
The java code for exporting the private key in PKCS #8 format
-
import java.io.File;
-
import java.io.FileInputStream;
-
import java.io.FileWriter;
-
import java.security.Key;
-
import java.security.KeyPair;
-
import java.security.KeyStore;
-
import java.security.KeyStoreException;
-
import java.security.NoSuchAlgorithmException;
-
import java.security.PrivateKey;
-
import java.security.PublicKey;
-
import java.security.UnrecoverableKeyException;
-
import java.security.cert.Certificate;
-
-
import sun.misc.BASE64Encoder;
-
-
public class ExportPrivateKey {
-
private File keystoreFile;
-
private String keyStoreType;
-
private char[] password;
-
private String alias;
-
private File exportedFile;
-
-
try {
-
}
-
}
-
return null;
-
}
-
-
BASE64Encoder encoder=new BASE64Encoder();
-
fw.write(“—–BEGIN PRIVATE KEY—–\n“);
-
fw.write(encoded);
-
fw.write(“\n“);
-
fw.write(“—–END PRIVATE KEY—–”);
-
fw.close();
-
}
-
-
-
ExportPrivateKey export=new ExportPrivateKey();
-
export.keyStoreType=args[1];
-
export.password=args[2].toCharArray();
-
export.alias=args[3];
-
export.export();
-
}
-
}
Posted in Java | 37 Comments »
This was very usefull. I also would like to know how to import public and private keys as well.
This should work ..
Key key={load key from file}…
Certificate cert={load cert from file} …
KeyStore keyStore = KeyStore.getInstance(”JKS”);
keyStore.load(null, “password”.toCharArray());
keyStore.setKeyEntry(”alias”, key, “password”.toCharArray(), cert);
Great website! Bookmarked! I am impressed at your work!
Thanks!!! Saved my life!
Thanks for publishing this – it was very useful!
Hi. I know this *should* work, and it has worked before, but suddenly I’m getting this every time:
Exception in thread “main” java.lang.NullPointerException
at ExportPrivateKey.export(ExportPrivateKey.java:43)
at ExportPrivateKey.main(ExportPrivateKey.java:61)
I’ve found other similar export implementations, and they all fail on any line that calls “getPrivate().” Any ideas? This is killing me, and I seem to be the only person in the world to suddenly have this problem. haha!
Great work, though, and thanks.
KeyStore.PrivateKeyEntry
KeyStore.SecretKeyEntry
KeyStore.TrustedCertificateEntry
is your code only useful for the first method?
[...] or removed and it consequently becomes difficult to find. The following instructions are from this page, which originally got them from here. Here is a summary of the steps needed to export a [...]
This is excellent! I really needed this tonight. Thank you for posting.
How do I export a public key from a keystore? Can I use the same program by just changing the APIS to getpublic key. Also how I convert a generated public key to OPENSSL complaint format. Appreciate any help on this!
A question:
Why do you:
{code}
PrivateKey privateKey=keyPair.getPrivate();
String encoded=encoder.encode(privateKey.getEncoded());
{code}
And then suggest to:
{{openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key -out exported.key}}
Isn’t there a simple way of doing that, by directly recover the uncrypted key from the privateKey object ?
This is because apache expects the key to be in PKCS8 format, which is different from what JKS stores, so we need openssl to convert to PKCS8
Has anybody tried and got it to work in real world? I’m curious. I didn’t seem to have any success myself.
Thanks,
jp
I’ve failed to get the code to work. Keep having “Password tampered” error. And then I found that the code assume that the storepass and keypass are the same.
It worked for me. Thanks!
Dear Anand,
Your program made our day. Thanks a lot.
Regards,
Prince Nishchal.N.E
Does someone know how to convert the PKCS#8 PEM format to SSL PEM format directly in Java (so without the openssl tool)?
Thanks for your help!
It really helps me!
The error of tempered keystore sais that you lanch program with wrong keystore name.
If we get NullPointer error, it means that Password for keystore is correct, but alias (with name you entered) is not in this keystore!
You need to find out a valid alias-name.
И для русских:
прога действительно работает!!!
Если вылезает ошибка tempered keystore, это значит, что вы указали неправильный пароль для keystore.
Если вылезает ошибка NullPointer error, значит пароль правильный, но вы указали неправильное имя alias
Well, how about only using keytool and openssl? Here’s how you do it: http://www.swview.org/node/191
How to import private key into keystore?
I want to do it using keytool, not using java class.
I found this post useful as well – and it worked for me…
“Exporting keystore private key with WSAS”
http://blog.facilelogin.com/2008/07/exporting-keystore-private-key-with.html
Key key=keystore.getKey(alias,password);
if(key instanceof PrivateKey) {
}
The key is not an instanceof PrivateKey
so it is throwing the following error.
java.lang.NullPointerException at ExportPrivateKey1.export(ExportPrivateKey1.java:81)
at ExportPrivateKey1.main(ExportPrivateKey1.java:117)
Exception in thread "main"
please tell me how to proceed.
my java version is 1.4
this is the way i have created keystores
keytool -genkey -alias a -keyalg RSA -validity 90 -storepass offline -ke
ystore a.p12
keytool -genkey -alias b -keyalg RSA -validity 90 -storepass offline -ke
ystore b.p12
--------- i exported via keytool its working
keystore -export -keystore b.p12 -storepass offline -file f1.cer -alias b
keytool -export -keystore b.p12 -storepass offline -file f1.cer -alias b
keytool -import -keystore a.p12 -storepass offline -alias b -file f1.cer
How do I resolve the null point er exception?
C:\Temp\ExportPKey>11:31:13.54>java -jar ExportPrivateKey.zip pskey JKS OrclSoft
jobs.bnl.gov privkey.txt
Exception in thread “main” java.lang.NullPointerException
at ExportPrivateKey.export(ExportPrivateKey.java:43)
at ExportPrivateKey.main(ExportPrivateKey.java:61)
C:\Temp\ExportPKey>11:31:28.43>dir *.zip
Volume in drive C has no label.
Volume Serial Number is 2C44-A0AD
Directory of C:\Temp\ExportPKey
09/27/2007 02:59 PM 2,292 ExportPrivateKey.zip
1 File(s) 2,292 bytes
0 Dir(s) 2,351,157,248 bytes free
C:\Temp\ExportPKey>11:31:54.87>dir pskey
Volume in drive C has no label.
Volume Serial Number is 2C44-A0AD
Directory of C:\Temp\ExportPKey
09/22/2008 12:09 PM 15,979 pskey
1 File(s) 15,979 bytes
0 Dir(s) 2,351,157,248 bytes free
C:\Temp\ExportPKey>11:32:00.79>
I found the problem, incorrect alias name!
Thanks Anyway
this only works if alias passwd equal to keystore passwd, corrected code below:
import org.apache.log4j.Logger;
import sun.misc.BASE64Encoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.security.*;
import java.security.cert.Certificate;
public class ExportPrivateKey {
private static final Logger _logger = Logger.getLogger(”utils.ExportPrivateKey”);
private File keystoreFile;
private String keyStoreType;
private char[] password;
private String alias;
private File exportedFile;
private char[] alias_password;
public static KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password) {
try {
Key key=keystore.getKey(alias,password);
if(key instanceof PrivateKey) {
Certificate cert=keystore.getCertificate(alias);
PublicKey publicKey=cert.getPublicKey();
return new KeyPair(publicKey,(PrivateKey)key);
}
} catch (UnrecoverableKeyException e) {
_logger.fatal(”Cannot access private key”, e);
} catch (NoSuchAlgorithmException e) {
_logger.fatal(”Cannot access private key”, e);
} catch (KeyStoreException e) {
_logger.fatal(”Cannot access private key”, e);
}
return null;
}
public void export() throws Exception{
KeyStore keystore=KeyStore.getInstance(keyStoreType);
BASE64Encoder encoder=new BASE64Encoder();
keystore.load(new FileInputStream(keystoreFile),password);
KeyPair keyPair=getPrivateKey(keystore,alias,alias_password);
PrivateKey privateKey=keyPair.getPrivate();
String encoded=encoder.encode(privateKey.getEncoded());
FileWriter fw=new FileWriter(exportedFile);
fw.write(”—–BEGIN PRIVATE KEY—–\n”);
fw.write(encoded);
fw.write(”\n”);
fw.write(”—–END PRIVATE KEY—–”);
fw.close();
}
public static void main(String args[]) throws Exception{
ExportPrivateKey export=new ExportPrivateKey();
export.keystoreFile=new File(args[0]);
export.keyStoreType=args[1];
export.password=args[2].toCharArray();
export.alias=args[3];
export.alias_password=args[4].toCharArray();
export.exportedFile=new File(args[5]);
export.export();
}
}
note that parameter list is changed, you need to specify alias password after alias name
got also some sample code at the following url:
http://proghowto.com/move-a-private-key-between-two-jks-keystore
if you are interested on how to move the keys from a keystore to the other one
Daniel
[...] http://www.anandsekar.com/2006/01/19/exporting-the-private-key-from-a-jks-keystore/ [...]
very very usefull
thank you
Anand++.
Worked for me, thanks!
This is very useful, thanks a lot for the info.
Sorry, this does NOT work for me.
I still have a nullpointer exception.
This the command I use, I know the keystore pwd and alias name are correct, since i opened it with keytool.
java -jar ExportPrivateKey.zip agent.truststore JKS changeit bla.domain.nl test.pem
Can anyone provide a solution?
If you get a null pointer exception and the keystore and private key password are different then change the keystore password to be the same as the private key. This worked for me. The command to change the keystore password is:
keytool -storepasswd -keystore {keystore_path}
I also get NullPointerException error. My keystore and private key password is the same. Any ideas?
Exception in thread “main” java.lang.NullPointerException
at ExportPrivateKey.export(ExportPrivateKey.java:43)
at ExportPrivateKey.main(ExportPrivateKey.java:61)
Getting this error:
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 4
at ExportPrivateKey.main(ExportPrivateKey.java:60)
I have found a bit corrected code on http://www.memofy.com/memofy/show/000863e71fa863e7008545a7bfe138/How_to_export_private_key_from_SUN_keystore
Supports different password for key and keystore.
java ExportPrivateKey keystoreFile keyStoreType password keypassword alias
Is Gettting MCSE Certified that important?