I have dabbled in activities related to SSL for a long time but each time it starts with a painful experience. Sometimes it also ends painfully. After reading articles, the Java API and using various tools and creating CSR’s and coding Symmetric encryption routines one would feel like a security expert.
Actually there is no reason to feel like an expert because we are only dabbling in security. So my explanations could be fraught with inaccuracies.
This whole affair is amateurish but I can at least blog about this.
Standards and RFC’s
I feel that they are very tricky. The first time I established Two-way SSL I felt that I have understood the difficult SSL protocol. I couldn’t have been more wrong about that because the procedure I followed then was only one of several ways to accomplish this. There are various formats like .pfx, .DER, .crt, .pem etc. and tools like OpenSSL help you convert one into the other.
In addition to that there seems to be various key store formats.
The bottom-line is that if one could read RFC 2246 and understand and code SSL libraries using Java API’s or BouncyCastle then everything would seem to be clear. But this information is quite complex and will be forgotten quickly.
CSR’s, TrustStores and KeyStores
The second time I generated a CSR I was tripped by a quirk which I haven’t understood fully. When I tried to import a CA-signed public key and the certificate chain back into my keystore I faced this error.
java.security.UnrecoverableKeyException: Cannot recover key.
This exception may result from the fact that you had provided a key password that was different from the keystore password when you generated the self-signed certificate
I realized that in fact the keystore and key passwords were different but I could not locate any such restriction anywhere.
Now the CA has sent the signed certificates already and I am not in a position to generate a new CSR and start the process all over again because some worthless managers are breathing down my neck.
Fortunately some coders have published libraries to do tricky security stuff. One such library is found at http://juliusdavies.ca/commons-ssl/download.html and the author recommended that I build my key store again and use a common password for the key as well as the store.
java -cp not-yet-commons-ssl-0.3.11.jar org.apache.commons.ssl.KeyStoreBuilder 'password' rsa.key
How do I get the private key from the Java KeyStore ?
It looked like J2SE 6 keytool allows us to export the contents including the private key from the store. These commands fail in J2SE 7.
"C:\Program Files\Java\jdk1.6.0_18\bin\keytool" -importkeystore -srckeystore keystore.jks -destkeystore mystore.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass srcstorepass -deststorepass deststorepass -srcalias srcalias -destalias destalias -srckeypass srckeypass -destkeypass destkeypass -noprompt
I had Cygwin and OpenSSL and I could execute this next step to convert pkcs12 the keystore that was created to a pem format using openssl
openssl pkcs12 -in mystore.p12 -out mystore.pem -passin pass:mysecret -passout pass:mysecret
So after this all the contents of the original key store are exported and ready to be built into a fresh KeyStore using not-yet-commons-ssl-0.3.11.jar and the procedure shown above.
Renewal of Certificates
The procedure for this is also different for IIS and simple Java Key stores. I received a new intermediate certificate from the CA because the old one expired. Now I tried to refresh my KeyStore and TrustStore but that was not quite easy till I understood how the certificates are stacked and sent.
This is RFC 2246
certificate_list
This is a sequence (chain) of X.509v3 certificates. The sender's
certificate must come first in the list. Each following
certificate must directly certify the one preceding it. Because
certificate validation requires that root keys be distributed
independently, the self-signed certificate which specifies the
root certificate authority may optionally be omitted from the
chain, under the assumption that the remote end must already
possess it in order to validate it in any case.
So the original certificate generated along with the public/private key pair was
signed by the sub root certificate which was in turn signed by the CA’s root. The CA had sent me a new sub root or intermediate certificate.
Another painful experience because I had to build the KeyStore again using not-yet-commons-ssl-0.3.11.jar and the same procedure shown above.
What if someone hadn’t published a library for this ? What is the alternative ? OpenSSL ?
I am not sure but there are a few libraries like this for manipulating Java KeyStores and viewing and converting certificates. These libraries complement each other in some cases and the desired result can be achieved without fully understanding ‘Security’.
Update :
It seems to me that still I have not understood enough about certificate renewal. Now there is a simpler procedure which I have missed earlier.
If we just export each old certificate – public key certificate, intermediate, root- and then just replace the old intermediate with the new one and import, the chain is refreshed in the KeyStore.
The order of certificates in the .pem file should be
- Public key certificate
- New Intermediate
- Root