Friday, December 12, 2014

Setting up a new local Certificate Authority

Create you own CA

Certificate Authorities provide certificates that is installed on the web server or application that are connected through a client. The browsers, like Mozilla or Chrome, trust these certificate because browsers comes prepacked with the root trust certificate for all these providers. These providers charge a hefty fee to provide the certificates.

However, you don't have to pay for the certificates if you install your own CA and use the local CA to issue the certificates. This can save you time and money when certificates are used in environments other than PRODUCTION.

When you access a site running your certificate, a warning will be displayed that the certificate is not from a trusted source. This also can be taken care of as we will see later.

The following blog used redhat linux for setting up but it could easily be used for other flavors. You will need to make sure that openssl is installed and is in the path.

1. Set up the directory structure

linux# mkdir /opt/CA
linux# cd /opt/CA
linux# mkdir csr certs conf private public signed-keys
linux# echo "01" > conf/serial
linux# touch conf/index

2. Set up the config file

linux# cd conf
linux# vi openssl.cnf

Copy the below in your openssl.cnf file

[ req ]
default_bits            = 2048
dir                     = /opt/CA
default_keyfile         = $dir/private/root.pem
default_md              = sha1
prompt                  = no
distinguished_name      = MY_CA
x509_extensions = v3_ca

[ MY_CA ]
countryName             = US
stateOrProvinceName     = NY
localityName            = NewYork
0.organizationName      = example.com
commonName              = example.com root CA
emailAddress            = ca@example.com

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true

[ ca ]
default_ca              = CA_default

[ CA_default ]
dir                     = /opt/CA
new_certs_dir           = $dir/signed-keys/
database                = $dir/conf/index
certificate             = $dir/public/root.pem
serial                  = $dir/conf/serial
private_key             = $dir/private/root.pem
x509_extensions         = usr_cert
name_opt                = ca_default
cert_opt                = ca_default
default_crl_days        = 30
default_days            = 3650
default_md              = sha1
preserve                = no
policy                  = policy_match

[ policy_match ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ usr_cert ]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
nsCaRevocationUrl     = https://example.com/ca-crl.pem

You may want to change the default bits, validity period or URL for revocation list to match your requirements. Other setting could be used as they are.

3. Generate the root key pair

linux# openssl req -nodes -config conf/openssl.cnf -days 3650 -x509 -newkey rsa:2048 -out public/root.pem -outform PEM

This will create the key pair n base64 format. Keep the private/root.pem safe. Provide public/root.pem to the clients along with user certs.

You could view the content of these key files using openssl command.

linux# openssl rsa -in private/root.pem -noout -text
linux# openssl x509 -in public/root.pem -noout -text

Some of the client may want the public key in DER format. To convert PEM to DER, use following:

linux# openssl x509 -in public/root.pem -outform DER -out public/root.der

4. Signing the Certificate

The party that needs the certificate will send you the Certificate Signing Request (CSR). Check the CSR before signing it.

linux# openssl req -in example.csr -noout -text

This will show the CSR details.

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: CN=example.com, OU=Example, O=example ou, L=New York, ST=NY, C=US
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c3:b7:32:bd:59:1e:a3:e5:42:66:3b:42:cb:db:
                    4a:5c:a8:ff:d3:f7:c1:ba:0b:8b:43:66:54:81:14:
                    ed:61:8b:d9:79:fa:51:43:ea:e0:26:17:39:bc:14:
                    14:eb:89:3e:73:6f:f4:0a:4e:90:46:68:d8:c0:b4:
                    0f:72:13:19:79:e6:90:bd:a4:d1:61:3e:63:a5:b3:
                    7a:ac:1c:9a:2c:75:a7:5b:84:78:60:66:3f:64:fe:
                    af:a0:09:bc:8e:09:9f:d6:b3:76:1d:4e:c4:76:f1:
                    21:f1:f8:36:05:2a:dd:d2:82:37:ff:cc:57:19:06:
                    ab:f6:a6:00:a2:24:12:2e:51:d5:8e:22:99:0b:be:
                    a0:94:e5:13:9b:b3:38:dc:3c:43:0a:a2:d2:6f:95:
                    6e:19:d6:0a:9b:13:d7:2e:0f:98:cf:78:aa:00:31:
                    a0:5d:83:10:2c:68:2c:8a:1f:25:32:c1:68:21:6d:
                    e6:d6:75:05:02:ec:d8:b8:86:36:ac:95:d1:8b:a7:
                    cf:d8:e7:2e:9d:d5:ed:36:5f:69:0b:e0:49:21:20:
                    81:96:bf:dc:00:d6:ed:6e:fa:28:95:f3:e7:72:b3:
                    b6:79:12:93:b8:47:5b:f6:25:33:17:86:8b:7d:9d:
                    ca:50:de:f6:03:87:57:f7:6a:c6:7f:9c:19:c8:cb:
                    45:67
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: md5WithRSAEncryption
         18:db:e5:33:7a:45:8d:70:c1:be:5c:95:b7:f6:2e:c4:d3:d3:
         de:45:ad:ce:d1:e8:8c:09:9b:21:37:97:99:7c:91:77:99:92:
         e9:47:cc:0e:11:5d:29:14:b0:be:11:a4:41:30:98:b7:1a:26:
         34:fc:77:92:c4:1e:62:c9:1f:11:cb:be:0f:37:5d:72:d7:6f:
         55:65:06:7b:50:42:ae:6b:46:77:ee:59:50:db:2b:b5:ed:bf:
         d3:21:a6:ac:b6:d6:fd:5e:2c:15:54:73:81:85:ce:52:5e:fe:
         ff:be:d3:2e:75:f9:cb:85:6b:bf:81:b8:10:09:4e:d7:57:5b:
         92:50:51:b2:f4:ef:3f:ee:30:de:fb:12:ba:86:8c:6e:03:20:
         50:70:50:85:22:d9:d7:df:2a:cb:d9:ef:98:fb:31:c8:cb:85:
         c7:25:0a:0b:40:30:29:4e:eb:1c:50:b4:de:eb:2d:d3:87:c4:
         1d:0b:fc:de:9a:58:48:3c:66:f5:07:3b:66:df:18:10:18:c2:
         9f:ed:b9:16:36:8b:78:6f:9e:e7:33:56:41:57:cb:99:8f:db:
         dd:8d:24:9b:8e:0b:af:b8:d6:29:3e:fe:6e:cb:26:70:ce:82:
         50:c9:c9:6e:6a:99:e8:44:67:87:a1:db:39:b3:a9:48:ad:0f:
         b5:ee:6c:22

Now sign the certificate

linux# openssl ca -batch -config conf -in csr/example.csr -out certs/example.pem

Now, certificate is ready in the directory /opt/CA/certs, you will need to send the user certificate, "certs/example.pem" and the trusted authroty (CA) certificate "public/root.pem" to the party that sent the CSR.

The requester will need to import the certificates to the web server in the order -- trusted cert "root.pem" than user cert "example.pem".

When you access the site now the warning will be displayed that certificate is not from a trusted source. To fix this, import the root.pem to the web browsers.

For Mozilla


goto options --> Advanced --> View Certficates --> Authorities , click on Import

Select the root.pem file --> select "Trust this CA to identify websites" --> ok

Now you will be able to see the certificate along with other trusted trusted certificates.

Access the site now. No warning will be displayed.

Similarly, you could import the root certificate for Chrome as well.


Have fun--



2 comments:

  1. When trying to sign a certificate using the following command:

    linux# openssl req -in example.csr -noout -text

    I am getting an error finding the default_ca. Any ideas what might be causing it?

    ReplyDelete
    Replies
    1. Mark,
      The option you mentioned are for viewing the CSR. It will require the proper setup for default_ca. check you openssl.cnf. It will have a section for default_ca
      [ ca ]
      default_ca = CA_default

      [ CA_default ]

      Set this section properly. The error should go away.

      Delete