Creating a Certificate Authority is easy. There are many scripts out there to do it for you. However, creating a CA that is easy to manage can be tricky. This should walk you through creating a CA and explain all the pieces.
Note: This page takes an extra step to make a fairly PKIX-compliant Certificate Authority. In pariticular, it ensures that the email address associated with your CA is in the SubjectAltName
extension rather than in the DN. The former is the PKIX and X509v3 standard way of presenting an email address while the later is the old X509v1 way.
mkdir CA
mkdir CA/{certsdb,certreqs,crl,private}
chmod 700 CA/private
touch CA/index.txt
This is where a list of all signed certs will go. Openssl will use this to keep track of what's happened.
cd CA
cp /etc/openssl.cnf .
Your system openssl.cnf may be in some place other than /etc/openssl.cnf
. If it's not there, try /usr/lib/ssl/openssl.cnf
or /usr/share/ssl/openssl.cnf
. If all else fails, run locate openssl.cnf
.
[ v3_req ]
section has subjectAltName = email:move
. If you'd prefer the old v1-style way of email in the Subject, simply remove this line.v3_ca
and usr_cert
sections. Then to the original's, we'll add the line SubjectAltName = email:move
. Again, this is necessary for a PKIX compliant CA. Skip this step if you prefer the old way. This will look like:#################################################################### # Extensions for when we sign normal certs (specified as default) [ usr_cert ] basicConstraints = CA:false subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer subjectAltName = email:move #################################################################### # Same as above, but cert req already has SubjectAltName [ usr_cert_has_san ] basicConstraints = CA:false subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer #################################################################### # Extensions to use when signing a CA [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:true subjectAltName=email:move #################################################################### # Same as above, but CA req already has SubjectAltName [ v3_ca_has_san ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = CA:true
The reason we have to do this is that if you have subjectAltName = email:move
set when signing a certificate that doesn't have an email in the subject (i.e. is already PKIX compliant), openssl will 'move' the email from the subject (since it's not there, that's null) to the SubjectAltName extension thus deleting the original. Remember, you use a section with the -extensions
arguement.
All of these options are explained in openssl.cnf page.
v3_ca
, v3_ca_has_san
, usr_cert
, and usr_cert_has_san
sections. To do that, add a line to each section as follows:Again, be sure to put this all 4 extension sections.
openssl req -new -newkey rsa:2048 -keyout private/cakey.pem -out careq.pem -config ./openssl.cnf
Here -new
denotes a new keypair, -newkey rsa:2048
specifies the size and type of your private key: RSA 2048-bit, -keyout
dictates where they new private key will go, -out
determines where the request will go, and -config
tells openssl to use our config rather than the default config.
Note that as of January 1, 2011, Microsoft will remove all CAs with keys of size 1024-bit or smaller from their browsers and OSes. You should be using 2048 or bigger anyway, but if you interact with Microsoft systems, you'll definitely have to ensure you set your keysize to 2048. The default for openssl is 1024, so be sure to specify it manually as we did above. Thanks to Chet Burgess for the pointer.
openssl ca -create_serial -out cacert.pem -days 365 -keyfile private/cakey.pem -selfsign -extensions v3_ca_has_san -config ./openssl.cnf -infiles careq.pem
Note the choice of v3_ca_has_san
here. If you prefer the old-style, simply use v3_ca
here instead.
-create_serial
is especially important. Many HOW-TOs will have you echo "01" into the serial file thus starting the serial number at 1, and using 8-bit serial numbers instead of 128-bit serial numbers. This will generate a random 128-bit serial number to start with. The randomness helps to ensure that if you make a mistake and start over, you won't overwrite existing serial numbers out there.
-out
determines where the self-signed certificate will go.
-days
determines how long the certificate will be valid for.
-keyfile
specifies the private key to use for signing (this was created in the last step).
-selfsign
tells openssl to use the data from the CSR when signing instead of expecting a CA CRT.
-extensions
tells openssl to use the v3_root_ca
section of the config we added above to determine what extensions to use.
-config
again specifies our config.
-infiles
specifies what to sign, which in this case is the CSR for our new CA.
Note that while you can use req
to create a self-signed certificate all in one step, req
does not support the '-create_serial' option, and does not leave the intermediate CSR for you (though you can generate later), and thus is not the best option.
You now have a functional Certificate Authority. See Managing your CA for information on signing certificates, creating CRLs, and other management tasks. If you need to change an existing CA, see Modifying your CA.