Create Your Own Certificate and CA

This page will show how to generate a key pair, a certificate signing request (CSR) using Java Keytool and set up your own CA using OpenSSL tool and sign a certificate. It will also explain all the trust issues associated with them. At the end it will show how to use the generated certificates to implement secure communication.

What You Need


You need the following set up in your Windows machine for this tutorial. You may not just read it but do it when you get time.

Java Keytool 

keytool is a key and certificate management utility. It allows users to administer their own public/private key pairs and associated certificates for use in self-authentication (where the user authenticates himself/herself to other users/services) or data integrity and authentication services, using digital signatures. It also allows users to cache the public keys (in the form of certificates) of their communicating peers.This comes with all JRE distribution under the bin directory. Make sure Java bin directory is in your path. Type at the command prompt "keytool -help". If it works then good otherwise append the Java bin path in your PATH system variable. The follwing command shows my machines Java bin path!

C:\> set PATH=%PATH%;C:\Program Files (x86)\Java\jre1.6.0_22\bin

Install OpenSSL 

You may be wondering how SSL comes here!  Am I writing with a glass of Single Molt Whiskey? No I may do sometimes but not here. As I said earlier SSL is the first communication layer where digital certificates were tried and used successfully. So the SSL community had do develop all the basic tools for digital certificates and their management. We are going to use this tool to set up our Test Certificate Authority. In this regard the OpenSSL Project is a collaborative effort to develop a robust, commercial-grade, full-featured, and Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) protocols as well as a full-strength general purpose cryptography library. 

You can download OpenSSL at http://openssl.org/related/binaries.html. In my machine I have installed "Win64 OpenSSL v1.0.0f" binary. Once the setup is finished you need to append the bin path in your system PATH variable.

c:\>set PATH=%PATH%;C:\OpenSSL-Win64\bin

Note: For the purpose of key pair generation, certificate management etc OpenSSL is alone sufficient and we do not need Java Keytool. But here we want to learn little bit about keytool as well, hence we going to use both. 

Set Up Directories

This is a trivial step. Create following directories under C drive of your computer. 
  • Keys: To store your private/public keys and certificates
  • CA: To store necessary certificates and keys or our own Test Certificate Authority.

Generate a Key Pair


To generate the key pair we are going to use Java keytool. Java stores keys and certificate in Key Store. A Key Store is password protected file often with JKS (Java Key Store) extension. In the command prompt, go to the Keys directory and type in the following command to generate a key pair, i.e. a private key and a public key.

C:\Keys>keytool -genkey -alias Deb -keystore DebKeyStore.jks -keyalg RSA -sigalg SHA1withRSA

Command Explanation:
genkey: Generate a key pair and add entry to the key store.
alias: short name of the key pair in the key store
keystore: This tells keytool that store the keys in a key store and file name of the key store is DebKeyStore.jks
keyalg: Key generation algorithm. Commonly it is either RSA (mostly used) or DSA (default). Here it is RSA.
sigalg: The signature algorithm. Here it says hash/digest the message with SHA1 and then encrypt it using a RSA private key. If you do not specify then keytool uses default key pair generation algorithm as "DSA". The signature algorithm is derived from the algorithm of the underlying private key: If the underlying private key is of type "DSA", the default signature algorithm is "SHA1withDSA", and if the underlying private key is of type "RSA", the default signature algorithm is "MD5withRSA".

When you run this command you will be asked to enter two password. These two passwords have different purposes.
  1. Key Store Password: You can consider that keytool will append this password to the content of the key store and then generate a hash/digest and store it into the key store. If someone modifies the key store without this password, he won't be able to update the digest message. The next time you run keytool on this keystore, it will note the mismatch and warn you not to use this key store anymore.
  2. Alias Password or Private Key Password: You need to provide an entry password to protect the entry for the alias, here Deb. You can consider that keytool will use this password to encrypt Deb's private key. This way other people won't be able to read Deb's private key.
For simplicity reasons all my passwords are Pass1word.
C:\Keys>keytool -genkey -alias Deb -keystore DebKeyStore.jks -keyalg RSA -sigalg SHA1withRSA
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  Debdayal Mandal
What is the name of your organizational unit?
  [Unknown]:  Banking Financial Service
What is the name of your organization?
  [Unknown]:  Cognizant
What is the name of your City or Locality?
  [Unknown]:  Lone Tree
What is the name of your State or Province?
  [Unknown]:  Colorado
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Debdayal Mandal, OU=Banking Financial Service, O=Cognizant, L=Lone Tree, ST=Colorado, C=US correct?
  [no]:  yes

Enter key password for <Deb>
        (RETURN if same as keystore password):


The "Keytool -genkey ..." command also prompts for alias's distinguish name (DN). A DN carries identity information of an entity in ASN.1 format. It consists of
  • Certificate owner's common name
  • Organization
  • Organizational unit
  • Locality or city
  • State or province
  • Country or region
To verify that the key pairs are added to the key store you can run the following command.

C:\Keys>keytool -list -v -keystore DebKeyStore.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: deb
Creation date: Jan 20, 2012
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Debdayal Mandal, OU=Banking Financial Service, O=Cognizant, L=Lone Tree, ST=Colorado, C=US
Issuer: CN=Debdayal Mandal, OU=Banking Financial Service, O=Cognizant, L=Lone Tree, ST=Colorado, C=US
Serial number: 4f19af71
Valid from: Fri Jan 20 11:16:17 MST 2012 until: Thu Apr 19 12:16:17 MDT 2012
Certificate fingerprints:
         MD5:  D1:81:5D:4B:DF:F0:6F:21:7A:08:C2:57:E6:1D:4D:F6
         SHA1: 6F:52:25:4E:04:6F:86:84:AE:93:7E:44:C1:1A:E7:90:B4:15:FC:05
         Signature algorithm name: SHA1withRSA
         Version: 3


*******************************************
*******************************************


While executing this command it will ask you to provide the key store password to verify the content of the file. You can list key store content without  providing the password with a "-protected" option. In that case it will show you a warning that key store content can not be verified. Note that keytool will not print the private or the public key. But it tells that key store has one entry and it of type PrivateKeyEntry. 

This command by default prints the MD5 fingerprint of a certificate. If the -v option is specified, the certificate is printed in human-readable format, with additional information such as the owner, issuer, and serial number. If the -rfc option is specified, certificate contents are printed using the printable encoding format, as defined by the Internet RFC 1421 standard.

Your Self-Signed Certificate


So now the key store DebKeyStore.jks has a private and public key. Key Store is not a digital certificate. It is a store to keep certificates and private keys. Now let us export a certificate containing the public key. You can not export the private key using keytool. To extract the private key you need to use Java Cryptography API. Use the following command to export the public key as a certificate.

C:\Keys>keytool -export -alias Deb -file Deb.cer -keystore DebKeyStore.jks
Enter keystore password:
Certificate stored in file <Deb.cer>

Now Deb.cer is the certificate containing your public key. Let us print the certificate using another keytool command.

C:\Keys>keytool -printcert -v -file Deb.cer
Owner: CN=Debdayal Mandal, OU=Banking Financial Service, O=Cognizant, L=Lone Tree, ST=Colorado, C=US
Issuer: CN=Debdayal Mandal, OU=Banking Financial Service, O=Cognizant, L=Lone Tree, ST=Colorado, C=US
Serial number: 4f19af71
Valid from: Fri Jan 20 11:16:17 MST 2012 until: Thu Apr 19 12:16:17 MDT 2012
Certificate fingerprints:
         MD5:  D1:81:5D:4B:DF:F0:6F:21:7A:08:C2:57:E6:1D:4D:F6
         SHA1: 6F:52:25:4E:04:6F:86:84:AE:93:7E:44:C1:1A:E7:90:B4:15:FC:05
         Signature algorithm name: SHA1withRSA
         Version: 3


Deb.cer is a self signed certificate. Its Owner and Issuer have the same DN. This certificate is signed by the private key of Deb. You can also open the certificate using Windows certification viewer tool. Double click the certificate in C:\>Keys folder and the certificate viewer will open.


Please note the red cross sign with the certificate which means the certificate is not trusted. We shall talk about the trust little later. For the time being let it be as not-trusted.


Generate a Certificate Signing Request


At this point you have a key pair in key store, i.e. DebKeyStore.jks and a certificate containing your public key and your DN as Deb.cer which is self signed. But browser does not trust you! Having a self signed certificate is not so much useful ha! To be trusted you need your certificate to be signed by a well known CA. To do that first you need to generate a Certificate Signing Request (CSR) and send it to CA. Keytool helps to generate a CSR using the following command

C:\Keys>keytool -certreq -alias Deb -keystore DebKeyStore.jks -file Deb.csr
Enter keystore password:Pass1word

The above command extracts required information such as public key, DN and put it in a standard CSR format in file Deb.csr. A commercial CA should verify all information before they can issue a certificate with their signature. In the next section we are going to create our own test CA and register it as trusted to the browser and use it to sign our public key.

Set Up a Certificate Authority


Hoping that you have already installed OpenSSL and appended its bin folder in your classpath, let us now try to setup a Test CA. Go to CA directory you created at the beginning. Here we are going to create a single tier CA, where root CA and issuing CA are the same. please follow the instruction carefully as mentioned below.

c:\>cd CA
c:\CA>set RANDFILE=rand

Openssl commands need to save a random seed information to a file ("random file"). You need to tell it the path to that file. Here, just tell it to use a file named "rand" in the current folder.

Next, to start Test CA, we need a private key. This is the top secret of the CA. If this is compromised then the CA is doomed!!! All certificates issued by this CA will be revoked. This is why the root private key is so important and often kept off-line necessitating a multi-tier hierarchy. For our test CA we need to create the key-pair and create a certificate signing request for the root CA's public key. Please note this CSR is for the CA itself. These two steps can be done in a single command using SSL as follows

C:\CA>openssl req -new -keyout cakey.pem -out careq.pem -config C:\OpenSSL-Win64\bin\openssl.cfg

Command Explanation:
req: work on certificate signing request
new: create a new private key and add a certificate request
keyout: keep the private key in file cakey.pem. Top secret file!!
out: write the CSR in file careq.pem
config: provides the config file. This is needed for the first time only.

When you run the above command it will ask our Test CA's DN and a password to encrypt the private key while writing in cakey.pem file.

C:\CA>openssl req -new -keyout cakey.pem -out careq.pem -config C:\OpenSSL-Win64\bin\openssl.cfg
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
..++++++
...................................................++++++
writing new private key to 'cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Colorado
Locality Name (eg, city) []:Lone Tree
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test CA
Organizational Unit Name (eg, section) []:Test CA
Common Name (e.g. server FQDN or YOUR name) []:Test CA
Email Address []:admin@testca.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
 
Please note we have done similar exercise with keytool for Deb's key-pair but not CA's key-pair. We could have used Openssl for Deb's key pair as well. 
Now we need to generate a certificate out of Test CA's CSR. Obviously this would be self signed. The following OpenSSL command is used to generate a self signed certificate form the CSR.

C:\CA>openssl x509 -signkey cakey.pem -req -days 3650 -in careq.pem -out caroot.cer -extensions v3_ca

Command Explanation:
x509: Work on an X.509 certificate
signkey: self sign the certificate using private in as stored in file cakey.pem
req: tells that input is a CSR
days: specify days of validity of the generated certificate
in: the input, i.e. CSR careq.pem
out: write the output certificate on caroot.cer
extensions: apply x.509 v3 extensions

C:\CA>openssl x509 -signkey cakey.pem -req -days 3650 -in careq.pem -out caroot.cer -extensions v3_ca
Loading 'screen' into random state - done
Signature ok
subject=/C=US/ST=Colorado/L=Lone Tree/O=Test CA/OU=Test CA/CN=Test CA/emailAddre
ss=admin@testca.com
Getting Private key
Enter pass phrase for cakey.pem:

At this point you have self signed root certificate of our Test CA. This certificate along with the private key will be used to sign others certificates. This root public certificate should be publicly available and must be trusted by browsers and programs.

You can open it using keytool or by Windows Certificate Viewer. 

C:\CA>keytool -printcert -v -file caroot.cer
Owner: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Issuer: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Serial number: a72306e92f637f4d
Valid from: Fri Jan 20 11:25:00 MST 2012 until: Mon Jan 17 11:25:00 MST 2022
Certificate fingerprints:
         MD5:  EE:46:08:66:CB:70:F4:BD:7D:B6:90:85:FD:8D:E2:14
         SHA1: FF:D9:7B:BA:E5:B0:51:20:CE:0E:79:8E:FE:E5:C1:76:8A:9F:62:DA
         Signature algorithm name: SHA1withRSA
         Version: 1

Here are the screen shots: 

Trusting CA's Root Certificate


Before signing Deb's certificate let us see how browser will trust Test CA's root certificate. Every browser keeps well know CA's root certificates in their trust store. Browsers manage (add/delete) these certificates during security patches time to time. While we can not convince Microsoft that please take our root CA cert, we are a trusted and respected CA, and send out a Windows security update but we can convince Windows installed in my own machine!

Open IE and click on Internet Options->Content->Certificates->Trusted Root Certification Authorities

You should see all well know CA's root certs there, like VeriSign, Entrust etc.

Let us add our Test CA's root certificate here. Click on import and follow instructions and select caroot.cer file from C:/>CA folder. When you finally hit finish button IE will show you the following warning:


Say YES, because we trust our Test CA.

Java Environment also keeps root CA certificates in C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts file. It is a keystore and you can open it using the following command. 

C:\Program Files (x86)\Java\jre1.6.0_22\lib\security>keytool -list -protected -keystore cacerts

*****************  WARNING WARNING WARNING  *****************
* The integrity of the information stored in your keystore  *
* has NOT been verified!  In order to verify its integrity, *
* you must provide your keystore password.                  *
*****************  WARNING WARNING WARNING  *****************

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 76 entries

digicertassuredidrootca, Jan 7, 2008, trustedCertEntry,
Certificate fingerprint (MD5): 87:CE:0B:7B:2A:0E:49:00:E1:58:71:9B:37:A8:93:72
trustcenterclass2caii, Jan 7, 2008, trustedCertEntry,
Certificate fingerprint (MD5): CE:78:33:5C:59:78:01:6E:18:EA:B9:36:A0:B9:2E:23
thawtepremiumserverca, Dec 2, 2009, trustedCertEntry,
Certificate fingerprint (MD5): A6:6B:60:90:23:9B:3F:2D:BB:98:6F:D6:A7:19:0D:46
swisssignsilverg2ca, Aug 13, 2008, trustedCertEntry,
Certificate fingerprint (MD5): E0:06:A1:C9:7D:CF:C9:FC:0D:C0:56:75:96:D8:62:13
swisssignplatinumg2ca, Aug 13, 2008, trustedCertEntry,
Certificate fingerprint (MD5): C9:98:27:77:28:1E:3D:0E:15:3C:84:00:B8:85:03:E6
equifaxsecureebusinessca1, Jul 18, 2003, trustedCertEntry,
Certificate fingerprint (MD5): 64:9C:EF:2E:44:FC:C6:8F:52:07:D0:51:73:8F:CB:3D
thawteserverca, Dec 2, 2009, trustedCertEntry,


...Rest of the lines are omitted for simplicity...



You can add Test CA's root certificate to your JRE using keytool command. The initial password of the "cacerts" keystore file is "changeit". You can also add the Test CA's root certificate in DebKeyStore.jks or your own key store and point to that key store at runtime when you need to use any certificate signed by this Test CA. If you cannot convince JRE that Test CA's root is trusted all certificates signed by Test CA will not work at runtime! You will see shortly how Test CA's cert can be added to DebKeyStore.jks.

Get Your Own Certificate Signed by CA


Test CA is ready, we have added it to the browser's truststore. Now it the time to get your own certificate signed by the Test CA. However, before that, you need to note that when a CA issues a new certificate, it will put a unique serial number into that certificate. So you need to tell OpenSSL what is the next serial number to use. To do that drop a serial.txt file containing a serial number in the CA directory. 

C:\CA>echo 1234>serial.txt
This way OpenSSL will use 1234 as the next serial number. Then it will set it to 1235 automatically. To sign Deb's public key and DN we now need the CSR which is Deb.csr and use the following OpenSSL command:

C:\CA>openssl x509 -CA caroot.cer -CAkey cakey.pem -CAserial serial.txt -req -in ../Keys/Deb.csr -out ../Keys/DebTestCA.cer -days 365

Command Explanation:
x509: again working with X.509 certificates.
CA: sign the certificate using caroot.cer. For exapmle it can find the DN of the CA here
CAkey: take the private key from cakey.pem file
CAserial: point to serial number file
req: says that input is a CSR and not a certificate itself
in: provides the input CSR as ../Keys/Deb.csr
out: write the output certificate in ../Keys/DebTestCA.cer file
days: validity of the certificate

C:\CA>openssl x509 -CA caroot.cer -CAkey cakey.pem -CAserial serial.txt -req -in ../Keys/Deb.csr -out ../Keys/DebTestCA.cer -days 365
Loading 'screen' into random state - done
Signature ok
subject=/C=US/ST=Colorado/L=Lone Tree/O=Cognizant/OU=Banking Financial Service/CN=Debdayal Mandal
Getting CA Private Key
Enter pass phrase for cakey.pem:


Now you have a certificate signed by Test CA, i.e. DebTestCA.cer. Let us open it using windows certificate viewer tool:


You can see that there are no red-cross mark with the certificate now. The DebTestCA is trusted as it is signed by Test CA which is trusted to the Windows/IE. Now whoever trust Test CA, will be able to trust the public key writtin in DebTestCA.cer and be able to send encrypted message to Deb. And Deb can decrypt the message using the private key stored in DebKeyStore.jks.

Keep Your Certificates in Key Store


You can separately keep the DebTestCA.cer and send it to clients or import DebTestCA.cer to the key store. Because that's the way to use the certificate in a Java application. But before that we need to import the signer certificate, i.e. root certificate of Test CA otherwise keytool will not import DebTestCA.cer. Because it would not be able to trust the signer.

While importing Test CA's root certificate keytool will ask for a confirmation that we really trust Test CA. If you say YES keytool will take all certificates signed by the root certificate. 

C:\Keys>keytool -import -alias TestCA -file ../CA/caroot.cer -keystore DebKeyStore.jks
Enter keystore password:
Owner: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Issuer: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Serial number: a72306e92f637f4d
Valid from: Fri Jan 20 11:25:00 MST 2012 until: Mon Jan 17 11:25:00 MST 2022
Certificate fingerprints:
         MD5:  EE:46:08:66:CB:70:F4:BD:7D:B6:90:85:FD:8D:E2:14
         SHA1: FF:D9:7B:BA:E5:B0:51:20:CE:0E:79:8E:FE:E5:C1:76:8A:9F:62:DA
         Signature algorithm name: SHA1withRSA
         Version: 1
Trust this certificate? [no]:  yes
Certificate was added to keystore

Import DebTestCA.cer which is now signed by Test CA. One point to note here is that while importing this certificate you have to specify the same alias name that was used to generate the key pair. Only then keytool will replace default self signed Deb's certificate with the certificate signed by Test CA. 

C:\Keys>keytool -import -alias Deb -file DebTestCA.cer -keystore DebKeyStore.jks

Enter keystore password:
Certificate reply was installed in keystore

We started with a empty key store and added several certificates in it while working on this tutorial. Let us see what all is there in the Key Store.

C:\Keys>keytool -list -v -keystore DebKeyStore.jks
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: deb
Creation date: Jan 20, 2012
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=Debdayal Mandal, OU=Banking Financial Service, O=Cognizant, L=Lone Tree, ST=Colorado, C=US
Issuer: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Serial number: 1235
Valid from: Fri Jan 20 11:32:06 MST 2012 until: Sat Jan 19 11:32:06 MST 2013
Certificate fingerprints:
         MD5:  D6:6B:9F:DC:DC:1E:B4:7C:31:31:C3:9B:0F:A7:91:CC
         SHA1: D0:19:C0:AC:9B:8F:7C:71:F6:F3:84:33:84:0A:88:A1:C3:A0:7F:60
         Signature algorithm name: SHA1withRSA
         Version: 1
Certificate[2]:
Owner: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Issuer: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Serial number: a72306e92f637f4d
Valid from: Fri Jan 20 11:25:00 MST 2012 until: Mon Jan 17 11:25:00 MST 2022
Certificate fingerprints:
         MD5:  EE:46:08:66:CB:70:F4:BD:7D:B6:90:85:FD:8D:E2:14
         SHA1: FF:D9:7B:BA:E5:B0:51:20:CE:0E:79:8E:FE:E5:C1:76:8A:9F:62:DA
         Signature algorithm name: SHA1withRSA
         Version: 1


*******************************************
*******************************************


Alias name: testca
Creation date: Jan 20, 2012
Entry type: trustedCertEntry

Owner: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Issuer: EMAILADDRESS=admin@testca.com, CN=Test CA, OU=Test CA, O=Test CA, L=Lone Tree, ST=Colorado, C=US
Serial number: a72306e92f637f4d
Valid from: Fri Jan 20 11:25:00 MST 2012 until: Mon Jan 17 11:25:00 MST 2022
Certificate fingerprints:
         MD5:  EE:46:08:66:CB:70:F4:BD:7D:B6:90:85:FD:8D:E2:14
         SHA1: FF:D9:7B:BA:E5:B0:51:20:CE:0E:79:8E:FE:E5:C1:76:8A:9F:62:DA
         Signature algorithm name: SHA1withRSA
         Version: 1


*******************************************
*******************************************

The key store has two entries. One PrivateKeyEntry  entry, it is basically a certificate chain now containing two certificates. The other trustedCertEntry entry, which is just a trusted self signed Test CA's root certificate. Here we learnt how to create a certificate, get it signed by a CA, import it back to keystore to create the whole certificate chain and all trust issues. Let us use these certificates to enable a SSL Communication. Later on when we shall try to actually program Web Service security, we shall create a client and a server certificate, get them signed by our test CA and use them in our program. 
 

Further Reading



Subpages (1): SSL Socket Communication
Comments