Your own certificate authority

If you want to run your website with https, or you want to use client verification, or any other SSL enabled mechanism you will need a certificate.

If you don’t want client verification you could create your own certificate using a self-signed certificate. But in this article I will explain how to run your own Certificate Authority, so you can sign your own certificates. No, browsers will still give you the warning unless you install the certificate of the CA.

In this example I use Red Hat Enterprise Linux 6.1, completely up-to-date.


Configure and initialize

I create a directory and I create the openssl.conf which will be used for this CA.

[root@ca ~]# mkdir -p /data/CA_falsyana
[root@ca ~]# cd /data/CA_falsyana
[root@ca CA_falsyana]# cp /etc/pki/tls/openssl.cnf .

In the openssl.cnf I edit a few variables like:

dir                             = /data/CA_falsyana           # Where everything is kept
countryName_default             = NL
stateOrProvinceName_default     = Zuid-Holland
localityName_default            = Capelle aan den IJssel
0.organizationName_default      = Falsyana
organizationalUnitName_default  = Test SSL Certificates

And I add a section which I will use for my website certificates. Also I add some section to make it possible to create Extended Validation (EV) certificates (the green bar in your browser).

[ server ]
basicConstraints        = CA:FALSE
nsCertType              = server
nsComment               = "OpenSSL Generated Server Certificate by Falsyana"
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid,issuer:always
keyUsage                = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage        = serverAuth
nsCaRevocationUrl       = https://www.falsyana.com/ca-crl.crl
crlDistributionPoints   = URI:https://www.falsyana.com/ca-crl.crl

Note: the URL in the last two entry’s much be reachable and the website serving those files must have a valid certificate as well. You could do it over non-ssl but the user will get a warning that not all content is encrypted.

I need to create a few directory’s and initialize some files:

[root@ca CA_falsyana]# mkdir certs csr newcerts private
[root@ca CA_falsyana]# echo 00 > serial
[root@ca CA_falsyana]# echo 00 > crlnumber
[root@ca CA_falsyana]# touch index.txt


Create CA certificate

Now we are ready to create the certificate for the CA

[root@ca CA_falsyana]# openssl req -new -x509 -extensions v3_ca -keyout private/cakey.key -out cacert.crt -days 3650 -config ./openssl.cnf
Generating a 2048 bit RSA private key
.....+++
....................................+++
writing new private key to 'private/cakey.key'
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) [NL]:
State or Province Name (full name) [Zuid-Holland]:
Locality Name (eg, city) [Capelle aan den IJssel]:
Organization Name (eg, company) [Falsyana]:
Organizational Unit Name (eg, section) [Test SSL Certificates]:
Common Name (eg, your name or your server's hostname) []:ca.falsyana.com
Email Address []:info@falsyana.com

[root@ca CA_falsyana]# openssl ca -gencrl -keyfile private/cakey.key -cert cacert.crt -out crl.pem -config ./openssl.cnf
Using configuration from ./openssl.cnf
Enter pass phrase for private/cakey.key:

[root@ca CA_falsyana]# cat cacert.crt crl.pem > cacert.pem

You have now configured and setup your own Certificate Authority, all you now need to do is receive (or create) requests and sign them with this CA.
NOTE: You must keep the file private/cakey.key always secret

Create and sign a certificate request

If you do this on a server that will use the certificate or on the server itself it doesn’t matter. I like to do it on the CA server so I have one location where I have everything.

First you need to create a private key and then you can create a certificate sign request with it.

[root@ca CA_falsyana]# openssl genrsa 1024 > private/client1.falsyana.com.key && openssl req -new -key private/client1.falsyana.com.key -out csr/client1.falsyana.com.csr -config ./openssl.cnf
Generating RSA private key, 1024 bit long modulus
...........++++++
.............................++++++
e is 65537 (0x10001)
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) [NL]:
State or Province Name (full name) [Zuid-Holland]:
Locality Name (eg, city) [Capelle aan den IJssel]:
Organization Name (eg, company) [Falsyana]:
Organizational Unit Name (eg, section) [Test SSL Certificates]:
Common Name (eg, your name or your server's hostname) []:test1.falsyana.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Now that you have a request you can sign it. Note if you want to use an recognized CA like GeoTrust this is the CSR file you send to them as well.

[root@ca CA_falsyana]# openssl ca -config openssl.cnf -policy policy_anything -cert cacert.pem -keyfile private/cakey.key -days 365 -extensions server -out certs/client1.falsyana.com.crt -infiles csr/client1.falsyana.com.csr
Using configuration from openssl.cnf
Enter pass phrase for private/cakey.key:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 0 (0x0)
        Validity
            Not Before: Jun 30 21:36:47 2011 GMT
            Not After : Jun 29 21:36:47 2012 GMT
        Subject:
            countryName               = NL
            stateOrProvinceName       = Zuid-Holland
            localityName              = Capelle aan den IJssel
            organizationName          = Falsyana
            organizationalUnitName    = Test SSL Certificates
            commonName                = test1.falsyana.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            Netscape Comment:
                OpenSSL Generated Server Certificate by Falsyana
            X509v3 Subject Key Identifier:
                B7:F2:00:8E:9F:6E:37:C3:F6:E8:3D:25:00:77:84:82:20:7B:41:EA
            X509v3 Authority Key Identifier:
                keyid:B0:9B:EB:52:73:B2:1B:48:74:72:9E:F5:6C:17:21:BA:91:C6:B5:6C
                DirName:/C=NL/ST=Zuid-Holland/L=Capelle aan den IJssel/O=Falsyana/OU=Test SSL Certificates/CN=ca.falsyana.com/emailAddress=info@falsyana.com
                serial:91:20:86:CB:B9:58:31:71

            X509v3 Key Usage:
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
Certificate is to be certified until Jun 29 21:36:47 2012 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Don’t forget to regenerate the revocation list, and publish it on the website.

As you can see in my command line i’m using the option -extensions server, which means this can basically only be used on a server and not on a client.

I have now a complete certificate the private key for the client is located in private/client1.falsyana.com.key and the certificate is in certs/client1.falsyana.com.crt

If you want to use this certificate on Windows you will need to convert it to a PKCS#12 format.

[root@ca CA_falsyana]# openssl pkcs12 -export -out certs/client1.falsyana.com.pfx -inkey private/client1.falsyana.com.key -in certs/client1.falsyana.com.crt -certfile cacert.crt

You have now a file called certs/client1.falsyana.com.pfx which can be imported on a Windows client.

Regenerate Revocation List

The revocation list is also a certificate, to regenerate this run this command:

[root@ca CA_falsyana]# openssl ca -gencrl -keyfile private/cakey.key -cert cacert.pem -out crl.pem -config ./openssl.cnf
[root@ca CA_falsyana]# /bin/cp crl.pem /data/mywebsites/falsyana.com/httpdocs/ca-crl.crl


Validate

To see if a certificate is valid you can run the following command:

[root@ca CA_falsyana]# openssl verify -CAfile cacert.pem -crl_check certs/client1.falsyana.com.crt
certs/client1.falsyana.com.crt: OK


Revoking a certificate

All certificates have a limited time before they need to be renewed. But sometimes you want to revoke a certificate before the expiration date, especially when you use certificates to authenticate clients with.

This can be done easily on the CA host, but it’s required to have the certificate, so don’t delete those from your CA.
To revoke a certificate run:

[root@ca CA_falsyana]# openssl ca -revoke certs/client1.falsyana.com.crt -keyfile private/cakey.key -cert cacert.pem -config ./openssl.cnf
Using configuration from ./openssl.cnf
Enter pass phrase for private/cakey.key:
Revoking Certificate 00.
Data Base Updated

[root@ca CA_falsyana]# openssl ca -gencrl -keyfile private/cakey.key -cert cacert.pem -out crl.pem -config ./openssl.cnf
Using configuration from ./openssl.cnf
Enter pass phrase for private/cakey.key:

[root@ca CA_falsyana]# cat cacert.crt crl.pem > cacert.pem

You must regenerate the crl certificate after you revoke a certificate.

If you now check if the certificate is valid you will get the following:

[root@ca CA_falsyana]# openssl verify -CAfile cacert.pem -crl_check certs/client1.falsyana.com.crt
certs/client1.falsyana.com.crt: C = NL, ST = Zuid-Holland, L = Capelle aan den IJssel, O = Falsyana, OU = Test SSL Certificates, CN = test1.falsyana.com
error 23 at 0 depth lookup:certificate revoked


Self-signed certificate

If you only want one certificate to test with, I can imagine setting up your own Certificate Authority might be a bit too much of a hassle. So you could simply just create a self-signed certificate from one command:

[root@ca CA_falsyana]# openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout private/selfsigned.key -out certs/selfsigned.crt -subj '/C=NL/ST=Zuid-Holland/L=Capelle aan den IJssel/CN=selfsigned.falsyana.com/'
Generating a 1024 bit RSA private key
....................++++++
............++++++
writing new private key to 'private/selfsigned.key'
-----

You have now the private key in private/selfsigned.key and the certificate in certs/selfsigned.crt

Extended Validation

Extended Validation, is that you will see a green bar in the browser to identify which company is running this website. The certificates generated above will not give that. They miss this extended part in the certificates.

It is possible to add it in the request, add it in the server but you still will not get a green bar. This is because the list of EV enabled Certificate Authority’s is hard coded in browsers.

Last words

This way you can run your own certificate authority, and once you install the cacert.crt as a trusted certificate authority on your desktop / laptop / other client, you will not even get the warning anymore of a not-trusted certificate.

If you want to go to the bigger public, you better pay for a certificate. As people don’t want to install your certificate first and it looks more professional if you have bought one. If you are going to run something like a webshop most certificate also give an warranty, most of the times starting at $10k.

One Response to “Your own certificate authority”

  1. avatar
    Yuji Saeki says:

    “It is possible to add it in the request, add it in the server but you still will not get a green bar. This is because the list of EV enabled Certificate Authority’s is hard coded in browsers.”

    Incorrect with IE. Add CA to Trusted Root CA\Certificates in certmgr.msc IE gets certs from storage. How can I add extended validation to my conf? (Only doing this for self-contained intranet stuff)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>