Creating digital certificates with our root certificate: Difference between revisions
m (Page started) |
(Finished CA cert creation part) |
||
Line 24: | Line 24: | ||
Now we can create an SSL certificate for a web server. For the Common Name of the certificate, we need the '''exact''' name of the web server that'll offer the SSL connections. However, some servers run different websites as Virtual Hosts, so they could be running, for example, www.saruman.biz, as well as shop.saruman.biz. That might present a problem, because if the certificate is issued for www.saruman.biz, then each visitor of shop.saruman.biz will get a warning along the lines of "Warning: The website you're trying to visit is shop.saruman.biz, but the certificate offered is for www.saruman.biz". To prevent that, we could use the wildcard character in the name of the certificate, so as to generate a certificate for *.saruman.biz. | Now we can create an SSL certificate for a web server. For the Common Name of the certificate, we need the '''exact''' name of the web server that'll offer the SSL connections. However, some servers run different websites as Virtual Hosts, so they could be running, for example, www.saruman.biz, as well as shop.saruman.biz. That might present a problem, because if the certificate is issued for www.saruman.biz, then each visitor of shop.saruman.biz will get a warning along the lines of "Warning: The website you're trying to visit is shop.saruman.biz, but the certificate offered is for www.saruman.biz". To prevent that, we could use the wildcard character in the name of the certificate, so as to generate a certificate for *.saruman.biz. | ||
=== CA.sh - certificate creation made easy=== | |||
openssl req -new -nodes -keyout saruman.biz. | Since we have the ''openssl.cnf'' set up just right, and the ''CA.sh'' script primed, generating an SSL certificate is not very hard. From any old directory, run as root | ||
This generates a new private key (named ''saruman.biz. | /usr/lib/ssl/misc/CA.sh -newreq | ||
This will create the signing request. The questions it'll ask, are | |||
* a PEM passphrase, with which to protect the private key of the key pair | |||
* Country/State/Locality/Organization/Organizational Unit; just as with the CA root certificate creation, these have your preprogrammed defaults that you may or may not change. | |||
* Common Name; here we MUST give the DNS name of the host that is going to use the certificate, e.g. ''shop.saruman.biz'', or ''*.saruman.biz''. | |||
* Challenge password; leave it blank, it's just to protect your signing request while en-route to the CA - but that's you anyway :-) | |||
* Optional company name; leave that blank too, it's also extra information for the CA. | |||
Now your private key and your certificate signing request (CSR) are ready; they're called ''newkey.pem'' and ''newreq.pem'' by default, and are located in your working directory. Time to do some signing! From that same working directory, run | |||
/usr/lib/ssl/misc/CA.sh -sign | |||
The script will show that it's using the config file ''/usr/lib/ssl/openssl.cnf'' (as we indeed wish), and then ask for the super-duper-secret passphrase to the CA private key (provided you've left that in directory ''/etc/ssl/ca/private''). Feed the script the passphrase, and it'll get to work. It'll check the request, then show you the details of the certificate you're about to sign. An example would be | |||
Certificate Details: | |||
Serial Number: 1 (0x1) | |||
Validity | |||
Not Before: Oct 27 09:34:00 2008 GMT | |||
Not After : Nov 1 09:34:00 2009 GMT | |||
Subject: | |||
countryName = NL | |||
stateOrProvinceName = Utrecht | |||
organizationName = Saruman.biz | |||
organizationalUnitName = Internet Dept. | |||
commonName = shop.saruman.biz | |||
emailAddress = webmaster@saruman.biz | |||
X509v3 extensions: | |||
X509v3 Basic Constraints: | |||
CA:FALSE | |||
Netscape Comment: | |||
OpenSSL Generated Certificate | |||
X509v3 Subject Key Identifier: | |||
30:F2:61:80:AA:CF:1B:F0:3E:44:41:D6:38:CC:31:F0:94:28:BD:2B | |||
X509v3 Authority Key Identifier: | |||
keyid:80:41:F8:A5:1F:C2:27:6E:CF:A9:28:8E:8A:EF:83:E7:FD:8A:D5:26 | |||
Certificate is to be certified until Nov 1 09:34:00 2009 GMT (370 days) | |||
Sign the certificate? [y/n]: | |||
After doing your CA duty and diligently checking all the data, just press ''y''. The script certifies the request, and asks if it is to commit the request. This means it'll update it's own database, by saving a copy of the signed certificate in ''/etc/ssl/ca/newcerts'' named after its serial number (''01.pem'' for this example). Furthermore the script will record the serial and ID's of the generated certificate so that the next certificate will have a new serial number. And now: hey presto! We have a ''newcert.pem'' in our working directory! | |||
For good measure: delete ''newreq.pem'', rename ''newkey.pem'' to ''shop.saruman.biz.key.pem'', and rename ''newcert.pem'' to ''shop.saruman.biz.pem''. Save the private key and its PEM passphrase in a safe place (e.g. Keepass database), and deploy your certificate! (more on that in another section). | |||
=== openssl - the hard way to certificate creation=== | |||
We don't actually need to use the ''CA.sh'' script, because we can do manually what the ''CA.sh'' script does. That gives us more control, but also more work. Let's see what we've got to do. | |||
We will now perform the first step in our "manual" certificate generation: we create a signing request with all the information that we want in our SSL certificate. We run the magic incantation - note how we already | |||
openssl req -new -nodes -keyout webmail.saruman.biz.key.pem -out webmail.saruman.biz.req.pem | |||
This generates a new private key (named ''webmail.saruman.biz.key.pem''), and a new, non-encrypted (because of ''-nodes''), key signing request named ''webmail.saruman.biz.req.pem''. We can leave out terms like ''-newkey rsa:2048'' and ''-days 370'' since we've put that in the configuration file. And naturally you're free to choose your own names for the keys. | |||
FIXME - need the full process here | |||
=== Validating the generated certificates=== | |||
Again, we can use the ''openssl'' command to validate the keys we've generated. For instance, the ''CA.sh'' generated certificate, after renaming, is verified with | |||
openssl x509 -in shop.saruman.biz.pem -noout -purpose | |||
Certificate purposes: | |||
SSL client : Yes | |||
SSL client CA : No | |||
SSL server : Yes | |||
SSL server CA : No | |||
Netscape SSL server : Yes | |||
Netscape SSL server CA : No | |||
S/MIME signing : Yes | |||
S/MIME signing CA : No | |||
S/MIME encryption : Yes | |||
S/MIME encryption CA : No | |||
CRL signing : Yes | |||
CRL signing CA : No | |||
Any Purpose : Yes | |||
Any Purpose CA : Yes | |||
OCSP helper : Yes | |||
OCSP helper CA : No | |||
Notice that the certificate is valid for everything except CA tasks. | |||
Likewise, using ''-dates'' instead of ''-purpose'' lets you see the validity time period, and ''-text'' gives the whole text of the certificate. Note the line marked "issuer", and see how your own CA is referenced there. |
Revision as of 09:09, 28 October 2008
Preparing for certificate creation
When we're going to create certificates, we're going to use the openssl command twice:
- once to create a "certificate signing request", in which we define all information to be included in the certificate, and actually generate the public and private key parts of the key pair, and
- once to instruct the OpenSSL package to sign the certificate with our CA root certificate.
The first step thus creates the actual keypair, and the second step signs the public key.
However, we're going to need to input a lot of parameters on the openssl command line. We can make things a bit easier for us by specifying these in the openssl.cnf file, just as we have added some values when creating the CA itself. To be precise, we're going to add X.509 V3 extensions
By default OpenSSL generates V1 certificates, but if we're not extremely worried about offending certain ancient web browsers, we can add V3 extensions, and even make openssl do that by default. To do this, we find in openssl.cnf the following line in the section [ req ], which is likely present but commented out:
req_extensions = v3_req # The extensions to add to a certificate request
Simply remove the # sign in front of it, so that it appears as given above. This by default enables V3 extensions.
Furthermore, check the section [ v3_req ]. It should look like this:
[ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier = hash
What is added is the last line, with subjectKeyIdentifier; this line specifies how to identify the public key being certified, so that distinct keys used by the same subject can be differentiated (e.g. as key updating occurs, for example). Four values are possible, but the IETF Public Key Infrastructure (PKIX) working group recommends the setting subjectKeyIdentifier=hash
Creating an SSL certificate
Now we can create an SSL certificate for a web server. For the Common Name of the certificate, we need the exact name of the web server that'll offer the SSL connections. However, some servers run different websites as Virtual Hosts, so they could be running, for example, www.saruman.biz, as well as shop.saruman.biz. That might present a problem, because if the certificate is issued for www.saruman.biz, then each visitor of shop.saruman.biz will get a warning along the lines of "Warning: The website you're trying to visit is shop.saruman.biz, but the certificate offered is for www.saruman.biz". To prevent that, we could use the wildcard character in the name of the certificate, so as to generate a certificate for *.saruman.biz.
CA.sh - certificate creation made easy
Since we have the openssl.cnf set up just right, and the CA.sh script primed, generating an SSL certificate is not very hard. From any old directory, run as root
/usr/lib/ssl/misc/CA.sh -newreq
This will create the signing request. The questions it'll ask, are
- a PEM passphrase, with which to protect the private key of the key pair
- Country/State/Locality/Organization/Organizational Unit; just as with the CA root certificate creation, these have your preprogrammed defaults that you may or may not change.
- Common Name; here we MUST give the DNS name of the host that is going to use the certificate, e.g. shop.saruman.biz, or *.saruman.biz.
- Challenge password; leave it blank, it's just to protect your signing request while en-route to the CA - but that's you anyway :-)
- Optional company name; leave that blank too, it's also extra information for the CA.
Now your private key and your certificate signing request (CSR) are ready; they're called newkey.pem and newreq.pem by default, and are located in your working directory. Time to do some signing! From that same working directory, run
/usr/lib/ssl/misc/CA.sh -sign
The script will show that it's using the config file /usr/lib/ssl/openssl.cnf (as we indeed wish), and then ask for the super-duper-secret passphrase to the CA private key (provided you've left that in directory /etc/ssl/ca/private). Feed the script the passphrase, and it'll get to work. It'll check the request, then show you the details of the certificate you're about to sign. An example would be
Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Oct 27 09:34:00 2008 GMT Not After : Nov 1 09:34:00 2009 GMT Subject: countryName = NL stateOrProvinceName = Utrecht organizationName = Saruman.biz organizationalUnitName = Internet Dept. commonName = shop.saruman.biz emailAddress = webmaster@saruman.biz X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 30:F2:61:80:AA:CF:1B:F0:3E:44:41:D6:38:CC:31:F0:94:28:BD:2B X509v3 Authority Key Identifier: keyid:80:41:F8:A5:1F:C2:27:6E:CF:A9:28:8E:8A:EF:83:E7:FD:8A:D5:26 Certificate is to be certified until Nov 1 09:34:00 2009 GMT (370 days) Sign the certificate? [y/n]:
After doing your CA duty and diligently checking all the data, just press y. The script certifies the request, and asks if it is to commit the request. This means it'll update it's own database, by saving a copy of the signed certificate in /etc/ssl/ca/newcerts named after its serial number (01.pem for this example). Furthermore the script will record the serial and ID's of the generated certificate so that the next certificate will have a new serial number. And now: hey presto! We have a newcert.pem in our working directory!
For good measure: delete newreq.pem, rename newkey.pem to shop.saruman.biz.key.pem, and rename newcert.pem to shop.saruman.biz.pem. Save the private key and its PEM passphrase in a safe place (e.g. Keepass database), and deploy your certificate! (more on that in another section).
openssl - the hard way to certificate creation
We don't actually need to use the CA.sh script, because we can do manually what the CA.sh script does. That gives us more control, but also more work. Let's see what we've got to do.
We will now perform the first step in our "manual" certificate generation: we create a signing request with all the information that we want in our SSL certificate. We run the magic incantation - note how we already
openssl req -new -nodes -keyout webmail.saruman.biz.key.pem -out webmail.saruman.biz.req.pem
This generates a new private key (named webmail.saruman.biz.key.pem), and a new, non-encrypted (because of -nodes), key signing request named webmail.saruman.biz.req.pem. We can leave out terms like -newkey rsa:2048 and -days 370 since we've put that in the configuration file. And naturally you're free to choose your own names for the keys.
FIXME - need the full process here
Validating the generated certificates
Again, we can use the openssl command to validate the keys we've generated. For instance, the CA.sh generated certificate, after renaming, is verified with
openssl x509 -in shop.saruman.biz.pem -noout -purpose Certificate purposes: SSL client : Yes SSL client CA : No SSL server : Yes SSL server CA : No Netscape SSL server : Yes Netscape SSL server CA : No S/MIME signing : Yes S/MIME signing CA : No S/MIME encryption : Yes S/MIME encryption CA : No CRL signing : Yes CRL signing CA : No Any Purpose : Yes Any Purpose CA : Yes OCSP helper : Yes OCSP helper CA : No
Notice that the certificate is valid for everything except CA tasks.
Likewise, using -dates instead of -purpose lets you see the validity time period, and -text gives the whole text of the certificate. Note the line marked "issuer", and see how your own CA is referenced there.