Sunday, July 15, 2012

Creating an X509v3 Certificate


There are three options to generate a certificate and some of the steps are common between the first two options.


Option1: Create a self signed certificate
We can use the keytool supplied as part of JDK to create this. For example:

  • Step1: Creating a Certificate

jdk1.7.0_04\bin>keytool -genkey -keyalg RSA -alias manojdefaultcert  -keystore manojkeystore.jks

  • Step 2: generating a CSR( Certificate Signing Request). 

The CSR contains the public key and the name of the server, in a format defined by the PKCS#10 standard (typically given the filename extension .p10 or .csr)
jdk1.7.0_04\bin>keytool -certreq -sigalg MD5withRSA -alias manojdefaultcert -file manojdefaultcert-csr.pem  -keystore manojkeystore.jks

  • Step3: Generate certificate from above CSR.

jdk1.7.0_04\bin>keytool -gencert -infile manojdefaultcert-csr.pem -outf
ile manojdefaultcert.cert -alias manojdefaultcert -keystore manojkeystore.jks

Don't recall if I had to do anything with the certificate generated in manojdefaultcert.cert file. Probably the PrivateKey entry in the keytool becomes ready for use.
Maybe we can  use this certificate and provide it to clients that want to trust this self signed certificate.

Option2: Create a Certificate signed by a CA

Steps 1 and 2 are similar to the ones for option 1. Once we have the CSR, we can get the CSR signed by a CA. Refer the  EJB CA post to see how EJBCA was setup as a CA and how we can get the cert signed by EJBCA.
  • Just to summarize, navigate to https://localhost:8443/ejbca/enrol/server.jsp  and select the CSR file and the user id to create against. 
    • User id should match the subject in "CN=subject". 
    • Output in pkcs#7 format.
  • Note: Remember to accept the return in pkcs#7 format from the CA and then import that file into the keystore. For some reason pem format didn't work in EJBCA. maybe because it didn't have the full chain. 
  • Step 3: Import the output file( CA Reply or CSR Reply) from the CA in keystore: 
    • This is typically given as an X.509 Certificate file (.cer, .crt, .pem, or .der) or as a PKCS#7 file (.p7b). In our case it is .p7b.
      • Each certificate in the chain must imported into the keystore(starting first with the root cert). If the CA Reply does not include the chain certificates, they must be added to the keystore manually before the CA reply. 
      • In our case .p7b includes the cert chain.
    • The command is:
      • keytool -importcert -alias testkeytoolcert -keystore testkey.jks -file "Manoj Test-testkeytoolcert-AdminCA1.pkcs7"
    • Basically we are trying to import the certificate returned from the CA using the same alias that was used to generate the PrivateKey entry. Keytool will assign the certificate chain to the PrivateKey and record the reply from the CA.

Option 3: Import an existing certificate ( in pkcs#12 format).

Basically, the certificate and keys were generated using a different tool or process or by an  internal company process. The cert and key information has to be combined into a single pkcs#12 format by using openSSL:
  • openssl pkcs12 -export -in cert.crt -inkey key.key -out exported.p12 -name tomcat -CAfile myCA.crt -caname root -chain

This certificate can then in imported in JKS keystore. 

Option 4: Programmatically create a Certificate signed by a CA using SCEP

This will be the subject of another blog post...
<TODO: insert link to blog post on SCEP Enrollment>


Resources



Free GUI replacement for the Java command-line utilities keytool, jarsigner and jadtool. KeyStore Explorer presents their functionality, and more, via an intuitive graphical user interface.

    • Free but not open source. Cannot redistribute.
    • Allows exporting of the PrivateKey.
    • Refer a utility in security-utils project for importing a private key and certs.

  • Importing private keys into a Java keystore using keytool

We need to convert our existing certificate and key into a PKCS12 file, and then use the keytool functionality to merge one keystore with another one. Java 6 can treat a PKCS12 file as a keystore so putting this together we get this:
    • keytool -importkeystore -deststorepass pwd -destkeypass pwd -destkeystore dest-keystore.jks -srckeystore src-certs-priv-key.p12 -srcstoretype PKCS12 -srcstorepass key-password -alias 1

The alias of 1 is required to choose the certificate in the source PKCS12 file, keytool isn't clever enough to figure out which certificate you want in a store containing one certificate.