Import private key and certificate into Java Key Store (JKS)
Apache Tomcat and many other Java applications expect to retrieve SSL/TLS certificates from a Java Key Store (JKS). Jave Virtual Machines usually come with keytool to help you create a new key store.
Keytool helps you to:
- create a new JKS with a new private key
- generate a Certificate Signung Request (CSR) for the private key in this JKS
- import a certificate that you received for this CSR into your JKS
Keytool does not let you import an existing private key for which you already have a certificate. So you need to do this yourself, here's how:
Let's assume you have a private key (key.pem) and a certificate (cert.pem), both in PEM format as the file names suggest.
PEM format is 'kind-of-human-readable' and looks like e.g.
-----BEGIN CERTIFICATE----- Ulv6GtdFbjzLeqlkelqwewlq822OrEPdH+zxKUkKGX/eN . . (snip) . 9801asds3BCfu52dm7JHzPAOqWKaEwIgymlk= ----END CERTIFICATE-----
Convert both, the key and the certificate into DER format using openssl :
openssl pkcs8 -topk8 -nocrypt -in key.pem -inform PEM -out key.der -outform DER openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
Now comes the tricky bit, you need something to import these files into the JKS. ImportKey will do this for you, get the ImportKey.java (text/x-java-source, 6.6 kB, info) source or the compiled (Java 1.5 !) ImportKey.class (application/octet-stream, 3.3 kB, info) and run it like
user@host:~$ java ImportKey key.der cert.der Using keystore-file : /home/user/keystore.ImportKey One certificate, no chain. Key and certificate stored. Alias:importkey Password:importkey
Now we have a proper JKS containing our private key and certificate in a file called keystore.ImportKey, using 'importkey' as alias and also as password. For any further changes, like changing the password we can use keytool.
this is exactly what I needed, as I have obtained a developer certificate from Symbian, but the cert request gen tool is a Symbian custom app, and thus generates its own private key.
However, the key it generates, does not appear to be in valid PEM format (at least according to openssl that complains about it):
D:\>d:\OpenSSL\bin\openssl pkcs8 -nocrypt -in ibw2.pem -inform PEM -out ibw2.der -outform DER
Enter PEM pass phrase:
Error decrypting key
4236:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:.\crypto\asn1\tasn_dec.c:1294:
4236:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:380:Type=X509_ALG
OR
4236:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:749:Field=
pkeyalg, Type=PKCS8_PRIV_KEY_INFO
4236:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:.\crypto\pem\pem_oth.c:83:
The key (well, not all of it) is something like this:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C83F3B63FAD97DA6
TYnfdy/1XQAtAL/R1gVGk1S0DLjXre8BK6fe6tLOzTLIxxczCVQjF9exPqjFypE7
uH9EleWc+7TLHkvN2QLtcG6wXewvHexhcjwjN3MiThrFB29BVDMgHyGf9ZHVUUqs
...
tZJeSwNF0lPJ6/wwwUeyaOJCu0xCSvhMCZ9FBaZgdX+a2s40Kqb/kiQlWPKoNqF6
gAz2xettQCCIV18c7fzHqXeHXics66Tau+3MpG3tN3o6efvJgQU7vw==
-----END RSA PRIVATE KEY-----
I am somewhat stuck in that I can't EXPORT the key from keytool to use in the CSR generator (from Symbian) and I can't import the key/certificate as obtained from Symbian.
Kinda Catch-22....
If you have any suggestions that would be massively appreciated, thanks
Marco
admin@infinitebw.com
int i = 0;
Iterator it = c.iterator();
while (it.hasNext()) {
certs[i] = (Certificate)it.next();
i++;
}
Next, I converted all SSL certs from PEM to DER and cat my cert, intermediate cert, and root cert into certs.der. After that, everything worked great.
Hope this helps anyone working with chained certs
I am not sure if this helps, but try adding -topk8 when converting. Hope this helps.
Barry
THE_NAME=name.dummy.com
export THE_NAME
openssl pkcs8 -topk8 -nocrypt -in ${THE_NAME}_key.pem -inform PEM -out ${THE_NAME}_key.der -outform DER
openssl x509 -in intermediateCA_cer.pem -inform PEM -out intermediateCA_cer.der -outform DER
openssl x509 -in ${THE_NAME}_cer.pem -inform PEM -out ${THE_NAME}_cer.der -outform DER
cat intermediateCA_cer.der ${THE_NAME}_cer.der > ${THE_NAME}_all_cer.der
javac *.java
java ImportKey ${THE_NAME}_key.der ${THE_NAME}_all_cer.der
keytool -list
But the keystore ony shows one entry, any ideas why is this happening?
Thanks,
Johann
What I did was:
changed certs = (Certificate[])c.toArray(); (line 147) to
(Certificate[])c.toArray(new Certificate[0]);
Then I ran the following script:
JAVA_HOME=/usr/java/latest
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
THE_NAME=www.dummy.org
export THE_NAME
rm /root/.keystore
rm /usr/share/tomcat5/.keystore
openssl pkcs8 -topk8 -nocrypt -in ${THE_NAME}_key.pem -inform PEM -out ${THE_NAME}_key.der -outform DER
openssl x509 -in rootCA_cer.pem -inform PEM -out rootCA_cer.der -outform DER
openssl x509 -in intermediateCA_cer.pem -inform PEM -out intermediateCA_cer.der -outform DER
openssl x509 -in ${THE_NAME}_cer.pem -inform PEM -out ${THE_NAME}_cer.der -outform DER
cat ${THE_NAME}_cer.der intermediateCA_cer.der rootCA_cer.der > ${THE_NAME}_all_cer.der
javac *.java
java ImportKey ${THE_NAME}_key.der ${THE_NAME}_all_cer.der
cp /root/keystore.ImportKey /root/.keystore
cp /root/.keystore /usr/share/tomcat5/.keystore
keytool -keypass changeit -storepass changeit -list
Thank you VERY much for this post and this Java code. And thanks to the others for their further comments and updates to the code.
I needed to build a cert that had three other intermediate certs combined with it. I pretty much did (manually) what johann did in hist second post and all worked perfectly.
Thanks to all of you for this valuable post.
Chris
instructed, it did created the file in my %User% home dir
but when I run Keytool -list, it doesn't find the file.
I tried a bunch of parameters ( like -file "C:\..." and so on)
I'm working inside a Novell network, does it matter????
I'm only asking cause I've encountered a post somewhere
that someone needed his IT people to delete and recreate
his User account in a Windows ENV to make the
Keytool -list to work
any information will be more then appreciated .
Ely.
openssl pkcs12 -in all.pfx -out all.pem
which I used as input to your two openssl commands above.
Thank you!
Peter.
programming is not necessary as java keytool supports transformation from one to another key store type using the parameter -importkeystore.
For example if you have the certificate and key in pkcs12 format you can use it out of the box:
keytool -importkeystore -srckeystore server.p12 -srcstoretype pkcs12 -destkeystore server.jks -deststoretype jks
If you have it in PEM you can convert it to pkcs12 first:
cat server_key.pem server_cert.pem server_cacert.pem > server.pem
openssl pkcs12 -export -out server.p12 -in server.pem
Actually when having PKCS12 you do not need to convert to JKS - you can probably use the keystore as it is just by setting the keystore type as PKCS12 in the configuration of your application.
C:\Users\Travis Thomas\Desktop\ImportKey>java ImportKey AKMClientPrivKey.der AKM
ClientSignedCert.der
Using keystore-file : C:\Users\Travis Thomas\Desktop\ImportKey\keyst2
HERE1
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: I
OException : algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
at java.security.KeyFactory.generatePrivate(Unknown Source)
at ImportKey.main(ImportKey.java:258)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, n
ot a sequence
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.pkcs.PKCS8Key.decode(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source)
at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source)
... 3 more
The .der files are from my boss, I believe they've been used for other tests successfully. The cert is self-signed, as the name would indicate. The newline that splits the cert name is present only due to the copy/paste, it's entered correctly on the commandline.
keytool -importkeystore -v -srckeystore conf/keystore.ImportKey -destkeystore conf/keystore.new -srcalias importkey -destalias tomcat
I had to change the alias from importkey to tomcat to make it work with my tomcat server
hth the next guy
George
Before you import the key, you need to change the password on the importkey alias ...
keytool -keystore keystore.ImportKey -keypasswd -new changeit -alias importkey
I am using the default "changeit" password here that is specified in your server.xml file -- adjust it to suit your needs :)