Create Your Own Certificate Authority






Create Your Own Certificate Authority

Sign your own certificates to use in securing your network.

SSL certificates are usually thought of as being used for secure communications over the HTTP protocol. However, they are also useful in providing both a means for authentication and a means for initiating key exchange for a myriad of other services where encryption is desired, such as POP and IMAP [Hack #54], SMTP [Hack #55], IPsec [Hack #93], and, of course, SSL tunnels [Hack #100]. To make the best use of SSL, you will need to properly manage your own certificates.

If an SSL client needs to verify the authenticity of an SSL server, the cert used by the server needs to be signed by a Certificate Authority (CA) that is already trusted by the client. Well-known CAs (such as Thawte and VeriSign) exist to serve as authoritative, trusted third parties for authentication. They are in the business of signing SSL certificates that are used on sites dealing with sensitive information (such as account numbers or passwords).

If a trusted authority has signed a site's SSL certificate, presumably it is possible to verify the identity of a server supplying that cert's credentials. However, for anything other than e-commerce applications, a self-signed certificate is usually sufficient for gaining all of the security advantages that SSL provides. Of course, an authority that the client recognizes must sign even a self-signed cert.

OpenSSL, a free SSL implementation, is perfectly capable of generating everything you need to run your own Certificate Authority. The CA.pl utility makes the process very simple.

In these examples, you'll need to type anything in boldface, and enter passwords wherever appropriate (they don't echo to the screen).


Creating the CA

To establish your new Certificate Authority, first change to the /misc directory under wherever OpenSSL is installed (/System/Library/OpenSSL on Mac OS X; /usr/ssl or /usr/local/ssl on most Linux systems). Then, use these commands:

$./CA.pl -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 1024 bit RSA private key
..........++++++
.....................++++++
writing new private key to './demoCA/private/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) []:US
State or Province Name (full name) []:Colorado
Locality Name (eg, city) []:Denver
Organization Name (eg, company) []:NonExistant Enterprises
Organizational Unit Name (eg, section) []:IT Services
Common Name (eg, fully qualified host name) []:ca.nonexistantdomain.com
Email Address []:[email protected]

Note that you don't necessarily need root permissions, but you will need write permissions on the current directory.

Congratulations! You're the proud owner of your very own Certificate Authority. Take a look around:

$ ls -l demoCA/
total 16
-rw-r--r--  1 andrew  andrew  1399  3 Dec 19:52 cacert.pem
drwxr-xr-x  2 andrew  andrew    68  3 Dec 19:49 certs
drwxr-xr-x  2 andrew  andrew    68  3 Dec 19:49 crl
-rw-r--r--  1 andrew  andrew     0  3 Dec 19:49 index.txt
drwxr-xr-x  2 andrew  andrew    68  3 Dec 19:49 newcerts
drwxr-xr-x  3 andrew  andrew   102  3 Dec 19:49 private
-rw-r--r--  1 andrew  andrew     3  3 Dec 19:49 serial

The public key for your new CA is contained in cacert.pem, and the private key is in private/cakey.pem. You can now use this private key to sign other SSL certs.

By default, CA.pl creates keys that are good for only one year. To change this behavior, edit CA.pl and change the line that reads:

$DAYS="-days 365";

Alternatively, you can forego CA.pl altogether and generate the public and private keys manually with a command like this:

$ openssl req -new -x509 -keyout cakey.pem -out cakey.pem -days 3650
            

This creates a key pair that is good for the next 10 years (to change that period, use a different argument to the -days switch). Additionally, you should change the private key's permissions to 600, to ensure that it is protected from being read by anyone.

Signing Certificates

So far, you've only created the Certificate Authority. To actually create keys that you can use with your services, you need to create a certificate-signing request and a key. Again, this can be done easily with CA.pl. First, create a certificate-signing request:

$ ./CA.pl -newreq-nodes
Generating a 1024 bit RSA private key
...++++++
...............................................++++++
writing new private key to 'newreq.pem'
-----
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) []:Denver
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NonExistant Enterprises
Organizational Unit Name (eg, section) []:IT Services
Common Name (eg, YOUR name) []:mail.nonexistantdomain.com
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:NonExistant Enterprises
Request (and private key) is in newreq.pem

If you want to encrypt the private key, you can use the -newreq switch in place of -newreq-nodes. However, if you encrypt the private key, you will have to enter the password for it each time the service that uses it is started. If you decide not to use an encrypted private key, be extremely cautious with your private key, as anyone who can obtain a copy of it can impersonate your server.

Now, to actually sign the request and generate the signed certificate, issue this command:

$ ./CA.pl -sign
Using configuration from /System/Library/OpenSSL/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Dec  3 09:05:08 2003 GMT
            Not After : Dec  3 09:05:08 2004 GMT
        Subject:
            countryName               = US
            stateOrProvinceName       = Colorado
            localityName              = Denver
            organizationName          = NonExistant Enterprises
            organizationalUnitName    = IT Services
            commonName                = mail.nonexistantdomain.com
            emailAddress              = [email protected]
        X509v3 extensions:
            X509v3 Basic Constraints: 
            CA:FALSE
            Netscape Comment: 
            OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
            94:0F:E9:F5:22:40:2C:71:D0:A7:5C:65:02:3E:BC:D8:DB:10:BD:88
            X509v3 Authority Key Identifier: 
            keyid:7E:AF:2D:A4:39:37:F5:36:AE:71:2E:09:0E:49:23:70:61:28:5F:4A
            DirName:/C=US/ST=Colorado/L=Denver/O=NonExistant Enterprises/OU=IT Services/
CN=Certificate [email protected]
            serial:00

Certificate is to be certified until Dec  7 09:05:08 2004 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
Signed certificate is in newcert.pem

Now you can set up keys in this manner for each server that needs to provide an SSL-encrypted service. It is easier to do this if you designate a single workstation to maintain the CA and all the files associated with it. Don't forget to distribute your CA cert [Hack #70] to programs that need to trust it.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows