Java/keystore
Notes
READ: Dealing with java keystores - http://www.startux.de/index.php/java/44-dealing-with-java-keystoresyvComment44
keytool - Key and Certificate Management Tool [1]
The cacerts Certificates File
A certificates file named "cacerts" resides in the security properties directory, java.home\lib\security, where java.home is the runtime environment's directory (the jre directory in the SDK or the top-level directory of the Java 2 Runtime Environment).
The "cacerts" file represents a system-wide keystore with CA certificates. System administrators can configure and manage that file using keytool, specifying "jks" as the keystore type. The "cacerts" keystore file ships with several root CA certificates with the following aliases and X.500 owner distinguished names
The initial password of the "cacerts" keystore file is "changeit". System administrators should change that password and the default access permission of that file upon installing the SDK.
# to create a custom keystore keytool -import -file MYCERT.cer -keystore /etc/keystore # to use the custom keystore -Djavax.net.ssl.trustStore=/etc/keystore
# Update default keystore cp /usr/java/jdk1.5.0_14/jre/lib/security/cacerts /usr/java/jdk1.5.0_14/jre/lib/security/cacerts.original keytool -import -file /root/tomcat.oeey.com.der.crt -keystore /usr/java/jdk1.5.0_14/jre/lib/security/cacerts
Verisign’s New Intermediate CA and You [2]
Import the CA Certificate into cacerts keytool -import -keystore <JAVA_HOME>jre\lib\security\cacerts -file NewVerisignIntermediateCA.cer The default cacerts password is “changeit”. Import the Signed Certificate into the Keystore keytool -import -keystore <keystore> -alias <alias> -file cert.cer -trustcacerts
Other References:
Java's Keytool and Client Digital Certificates [3]
Quick Import
To import key to custom keystore (use any password):
$ keytool -import -keystore /keystore -alias localhost -trustcacerts -file localhost.der.crt
To view that the key was imported to keystore (use password entered when creating keystore):
$ keytool -list -keystore /keystore
To use custom keystore, append this to application startup parameters:
-Djavax.net.ssl.trustStore=/keystore
Default Keystore
"Obtaining a copy of the certificate in X.509 format requires Microsoft’s Internet Explorer. By placing the https URL into the browser window, a dialog will pop up requesting permission to accept the certificate. Click the View Certificate button and then the Details tab. In this tab, click the Copy to File button, then click Next and select the Base-64 encoded X.509 (.CER) option. After that, click Next to save the resulting file." [4]
The default keystore is located:
.../jre/lib/sercurity/cacerts password: changeit
To import a certificate into the default keystore:
cd .../jre/lib/security/ keytool.exe -import -storepass changeit -file mycert.cer -keystore cacerts -alias mycert
Keytool
View certificates
$ keytool -list -keystore <keystore> $ keytool -list -v -keystore <keystore>
Conversion from Apache PEM to Java Keytool
Converting the certificate is easy. Converting the private key is less so.
- OpenSSL to Keytool Conversion tips [5]
- Conflicts OpenSSL versus KeyTool [6]
- Using OpenSSL to set up your own CA [7]
The .crt files provided by the CA do not need conversion, as they are in a standard format.
Convert openssl to keytool using Jetty:
# convert to pkcs12 openssl pkcs12 -export -in [domain].crt -inkey [domain].key -out keystore.pkcs12
# convert to java keystore (jks) # wget ftp://ftp.mortbay.org/pub/jetty-6.1.x/jetty-6.1.3.zip wget http://dist.codehaus.org/jetty/jetty-6.1.x/jetty-6.1.3.zip unzip jetty-6.1.3.zip java -classpath jetty-6.1.3/lib/jetty-6.1.3.jar org.mortbay.jetty.security.PKCS12Import keystore.pkcs12 keystore.jks
# verify keytool -list -v -keystore keystore.jks
# rename default alias of '1' to something else like 'tomcat' keytool -keyclone -keystore keystore.jks -alias 1 -dest tomcat keytool -delete -keystore keystore.jks -alias 1
Godaddy Converion (for mail and jira server with intermediate chain) [8]:
keytool -import -keystore keystore.jks -alias godaddy -trustcacerts -file [godaddy].crt cp keystore.jks ~/.keystore
wget https://certs.godaddy.com/repository/gd_bundle.crt openssl pkcs12 -export -chain -CAfile gd_bundle.crt -in <name of your certificate> \ -inkey <name of your certificate private key file> -out keystore.tomcat -name tomcat -passout pass:changeit # Add the following directives to the Connector tag: keystoreFile=<path to>/keystore.tomcat keystorePass="changeit" keystoreType="PKCS12"
If you only need to import a certificate (not private key), this is easy: [9]
keytool -import -alias [alias] -keystore cacerts -file [cert.pem]
Makefile:
all: cat TrustedSecureCertificateAuthorityDV.crt USERTrustRSAAddTrustCA.crt AddTrustExternalCARoot.crt > bundle.crt rm tomcat.keystore openssl pkcs12 -export -chain -CAfile bundle.crt -in ssl.oeey.com.crt -inkey ssl.oeey.com.key -out tomcat.keystore -name tomcat -passout pass:PASSWORD cp tomcat.keystore /etc
Conversion from Java Keytool to Apache PEM
encryption - Converting a Java Keystore into PEM Format. - Stack Overflow
http://www.google.com/#sclient=psy&q=convert+java+keystore+to+pem
keytool -keystore foo.jks -genkeypair -alias foo \ -dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU'
keytool -keystore foo.jks -exportcert -alias foo | \ openssl x509 -inform der -text
keytool -importkeystore -srckeystore foo.jks \ -destkeystore foo.p12 \ -srcstoretype jks \ -deststoretype pkcs12
openssl pkcs12 -in foo.p12 -out foo.pem
openssl x509 -text -in foo.pem
openssl dsa -text -in foo.pem
Command summary - to create JKS keystore:
keytool -keystore foo.jks -genkeypair -alias foo \ -dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU'
Command summary - to convert JKS keystore into PKCS#12 keystore, then into PEM file:
keytool -importkeystore -srckeystore foo.jks \ -destkeystore foo.p12 \ -srcstoretype jks \ -deststoretype pkcs12
openssl pkcs12 -in foo.p12 -out foo.pem
if you have more than one certificate in your JKS keystore, and you want to only export the certificate and key associated with one of the aliases, you can use the following variation:
keytool -importkeystore -srckeystore foo.jks \ -destkeystore foo.p12 \ -srcalias foo \ -srcstoretype jks \ -deststoretype pkcs12
openssl pkcs12 -in foo.p12 -out foo.pem
Command summary - to compare JKS keystore to PEM file:
keytool -keystore foo.jks -exportcert -alias foo | \ openssl x509 -inform der -text
openssl x509 -text -in foo.pem
openssl dsa -text -in foo.pem
Well, OpenSSL should do it handily from a #12 file:
openssl pkcs12 -in pkcs-12-certificate-file -out pem-certificate-file openssl pkcs12 -in pkcs-12-certificate-and-key-file -out pem-certificate-and-key-file
References
How to Import a Certificate into your Java Keystore
How to Import a Certificate into your Java Keystore
Author: Kenneth Burgener
Created: 2007.06.28
Summary
When you attempt to access a website protected by SSL (HTTPS) that is not trusted, the browser is kind enough to present you with a warning message, and give you the opportunity to accept the certificate. Java, by default, is not as nice. The default behavior for the Java connector attempting to access an untrusted certificate is to throw an exception. This exception generally looks like this:
Caused by: javax.net.ssl.SSLHandshakeException : sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
To resolve this issue, there are two options. You can either override the Java connector behavior (requires modifying code), or you can import the untrusted certificate into a keystore and implicitly trust the certificate.
Override Java Connector Behavior
Since this is probably not the preferred method I will simply provide some references here. One example of why you may want to change the default behavior would be if you would like to provide a prompt to the user asking if they wish to accept the certificate, much as any Internet browser would.
References
Customizing SSL in HttpClient
http://jakarta.apache.org/commons/httpclient/sslguide.html
SSL and Self Signed Certs
http://weblogs.java.net/blog/rbair/archive/2006/10/ssl_and_self_si_1.html
How to make JVM to accept self-sign certificate from server
http://forum.java.sun.com/thread.jspa?threadID=735919&messageID=4228600
Java Certification Path API Programmer's Guide
http://java.sun.com/j2se/1.4.2/docs/guide/security/certpath/CertPathProgGuide.html
Importing Certificate into a Keystore
A keystore is simply a Java container file which contains certificates and private keys. To import a certificate into a keystore, you will use "keytool". Key management in Java is done with the "keytool" application.
keytool - Key and Certificate Management Tool
http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html
The first step will be to obtain a copy of the certificate you wish to import. This is done easily with Internet Explorer. Simply visit the site you wish to obtain the certificate from. Since the certificate is untrusted, you will be presented with a warning message. Accept the warning. The next step is to click on the "lock" icon in your browser (bottom right of window in IE6, top next to address bar in IE7).
Clicking on the lock will bring up a short message. Click on the "View Certificate" link. The first tab, titled "General" gives you the option to import the certificate into Internet Explorer's trusted list. This would be a good time to do this if you wish to be able to visit the site in the future without warnings. The second tab titled "Details" has a "Copy to File" button. Click on the "Copy to File" button to begin the certificate export wizard. Click next to be presented with the "Export File Format" options. Select "Base-64 encoded X.509 (.CER)" option and click next. Give the file a name and a location (ie. C:\mycert.cer) and click next. Click the finish button and the file will be exported. Now that we have a certificate we can import it into a keystore.
There are two keystore options for storing a certificate. We can import the certificate into a keystore that we create, and tell our application where to find the keystore in the startup parameters. The second option is to import the certificate into the JRE's default keystore.
Import Certificate to Custom Keystore
To create a custom keystore we will use the keytool application as such:
keytool -import -keystore c:\keystore -file c:\mycert.cer -alias mycert
The location of the keystore file is arbitrary. The alias simply needs to be a unique name in the keystore. This alias is what will be used to reference the certificate in the future.
To use the keystore with your Java application, simply append the following parameter:
-Djavax.net.ssl.trustStore=c:\keystore
If your application needs to modify the keystore, you will probably need to append the keystore password paremeter as well:
-Djavax.net.ssl.trustStorePassword=XXX
Now your application should work without SSL warning issues.
Import Certificate to Default Keystore
The Java JVM contains a default keystore which contains many root level CAs (Certificate Authorities), such as Verisign and Thawte. Certificates that are signed by these CAs are implicitly trusted by Java. We can add our self signed certificate to this keystore, which will then allow our certificate to be trusted by any Java application that uses this JVM. This keystore is located here:
$JVM_PATH/lib/security/cacerts
This could be something like one of the following, or it could be within your application's folder if a JVM was installed with the application:
C:\Program Files\Java\jdk1.5.0_08\jre\lib\security\cacerts C:\Program Files\Java\jre1.6.0_01\lib\security\cacerts
To import a certificate to the default keystore we will use the keytool application as such:
keytool -import -keystore C:\Program Files\Java\jdk1.5.0_08\jre\lib\security\cacerts -file c:\mycert.cer -alias mycert -storepass changeit
The cacerts keystore contains a default password of "changeit". The location of the cacerts keystore file is dependent on the location of your JVM. The alias simply needs to be a unique name in the keystore. This alias is what will be used to reference the certificate in the future.
Now your application should work without SSL warning issues.
Other References
Testing with untrusted Https
http://www.testearly.com/2006/04/05/testing-with-untrusted-https/
See Also
SSL Certificates openssl keytool Java Keystore