SSL and Certificate Authorities
Written by dkg and jrollins.
Creating a certificate authority
Create a new root certificate authority (CA). You do this by generating a
private key for the CA, and creating a self-signed certificate from that key.
We'll call these two pieces the 'CA-key' and the 'CA-cert'. They are generated
on a machine we'll call the CA-host. If you can have a dedicated machine as
CA-host, that would be great.
ca-host$ mkdir -p /path/to/your.domain.org-CA/{private,certs}
ca-host$ cd /path/to/your.domain.org-CA
ca-host$ openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 3652
ca-host$ openssl x509 -in cacert.pem -out cacert.crt
The CA-key never leaves CA-host. CA-key should be chmod 0400. it's best if
CA-host is off-net itself, so data can only be transferred via physical media.
Distribute the CA-cert freely, and make sure that all your client machines
know about it and trust it to identify hosts and users.
Setting up new SSL services
Say you want to set up a new service using SSL on some host we'll call
'service-host'. On service-host, generate a new key and a certificate request
(this is *not* a certificate). When you generate the key and the cert-req, make
sure that you use the fully-qualified domain name (FQDN) for the Common Name
field. The FQDN is the hostname that other machines will use to access this
host for the given service. We'll call these two pieces 'service-key' and
'service-req'.
service-host$ openssl req -nodes -days 365 -new -keyout service-host_service_key.pem -out service-host_service_req.pem
The service-key never leaves service-host. It should be readable only as
root, or if the service runs as a separate user without starting as root and
then dropping privileges, service-key should be readable only as that user.
The service-req can be distributed freely. It isn't useful, however, until
it's signed by some CA which your clients trust. So hand it off to CA-host.
On CA-host, sign service-req with CA-key. This generates a certificate which
we'll call 'service-cert'.
ca-host$ openssl ca -in service-host_service_req.pem -out service-host_service_cert.pem
Service-cert can be distributed freely. It's not useful for initiating SSL
connections, however, unless you also control service-key. So put a copy of it
back on service-host, and point your software to it.
Clients who trust your CA (because they have a copy of CA-cert which they
trust) can now securely connect to service-host smoothly, without any SSL
errors.
The process outlined in this section can be repeated for each new
service-host.
Observations
- Service-host doesn't technically need to have a copy of CA-cert, unless it
plans to be a client to other services verified by your CA. That said, it
doesn't hurt to put it there.
- There is no such thing as a "certificate key". There are three
types of entities being passed around here: keys, certificates, and
certificate requests.
- The *only* entity which can be used to sign something else is a
key. A key is analogous to a GPG private key.
- A certificate request is analogous to an unsigned GPG public key,
aggregated with identifying information about the
individual/host/org/service/whatever who's claiming to control the private
part of the keypair.
- A certificate is simply a certificate request signed by some key.
- If you can use 2048-bits (or more) for every key you create, that
would be good, forward-looking work.
- Certificates have an expiration date on them. When a cert expires,
good TLS/SSL clients will avoid using it, and refuse to make a
connection. The farther into the future you make the expiration
date, the simpler it is to administer, but the larger your
vulnerability window is in the event of a compromise. Generally
people make the CA-cert extremely long-lived (10 years), and the
individual server-cert relatively short (1 month->1 year). You
will need to generate a new server-cert before the old server-cert
expires, and push it to server-host. This can be done using the
same server-req from last time, as long as you know that server-key
has not been compromised.
- There are mechanisms for publishing certificate revocations. They
are (sadly) not in wide use. A Certificate revocation for server-cert would
be published by the CA to a predefined location (the Certificate Revocation
List, or CRL) when the CA gets knowledge that server-key has been
compromised. Well-behaved TLS/SSL clients will check the CRL for
revocations before accepting a certificate. You will be a super-vanguard CA
if you actually decide to maintain a CRL, and keep it up-to-date. This
introduces a fourth entity into the mix beyond keys, certs, and requests. A
revocation is basically a certificate, bundled with a declaration
of revocation, all signed by the CA-key. A CRL should just be an
aggregation of revocations. I think. I still need to learn more
about managing revocations.
- Note that no one ever gets to see any of the keys unless they are
actually the real-world entity responsible for that key. This is
what makes it successful PKI.
Other useful commands
ca-host$ openssl x509 -noout -fingerprint
External Links
openssl
certificate doc
Last modified: Mon Feb 19 18:02:27 EST 2007