During my search, I found several ways of signing a SSL Certificate Signing Request:
Using the
x509
module:openssl x509 -req -days 360 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
Using the
ca
module:openssl ca -cert ca.crt -keyfile ca.key -in server.csr -out server.crt
Note: I am unsure of the use of the right parameters for this one. Please advise correct usage if I am to use it.
What way should one use to sign certificate requests with your Certification Authority? Is one method better than the other (for example, one being deprecated)?
In addition to answer of @jww, I would like to say that the configuration in openssl-ca.cnf,
defines the default number of days the certificate signed by this root-ca will be valid. To set the validity of root-ca itself you should use '-days n' option in:
Failing to do so, your root-ca will be valid for only the default one month and any certificate signed by this root CA will also have validity of one month.
You are missing the prelude to those commands.
This is a two-step process. First you set up your CA, and then you sign an end entity certificate (a.k.a server or user). Both of the two commands elide the two steps into one. And both assume you have a an OpenSSL configuration file already setup for both CAs and Server (end entity) certificates.
First, create a basic configuration file:
Then, add the following to it:
The fields above are taken from a more complex
openssl.cnf
(you can find it in/usr/lib/openssl.cnf
), but I think they are the essentials for creating the CA certificate and private key.Tweak the fields above to suit your taste. The defaults save you the time from entering the same information while experimenting with configuration file and command options.
I omitted the CRL-relevant stuff, but your CA operations should have them. See
openssl.cnf
and the relatedcrl_ext
section.Then, execute the following. The
-nodes
omits the password or passphrase so you can examine the certificate. It's a really bad idea to omit the password or passphrase.After the command executes,
cacert.pem
will be your certificate for CA operations, andcakey.pem
will be the private key. Recall the private key does not have a password or passphrase.You can dump the certificate with the following.
And test its purpose with the following (don't worry about the
Any Purpose: Yes
; see "critical,CA:FALSE" but "Any Purpose CA : Yes").For part two, I'm going to create another configuration file that's easily digestible. First,
touch
theopenssl-server.cnf
(you can make one of these for user certificates also).Then open it, and add the following.
If you are developing and need to use your workstation as a server, then you may need to do the following for Chrome. Otherwise Chrome may complain a Common Name is invalid (
ERR_CERT_COMMON_NAME_INVALID
). I'm not sure what the relationship is between an IP address in the SAN and a CN in this instance.Then, create the server certificate request. Be sure to omit
-x509
*. Adding-x509
will create a certificate, and not a request.After this command executes, you will have a request in
servercert.csr
and a private key inserverkey.pem
.And you can inspect it again.
Next, you have to sign it with your CA.
You are almost ready to sign the server's certificate by your CA. The CA's
openssl-ca.cnf
needs two more sections before issuing the command.First, open
openssl-ca.cnf
and add the following two sections.Second, add the following to the
[ CA_default ]
section ofopenssl-ca.cnf
. I left them out earlier, because they can complicate things (they were unused at the time). Now you'll see how they are used, so hopefully they will make sense.Third, touch
index.txt
andserial.txt
:Then, perform the following:
You should see similar to the following:
After the command executes, you will have a freshly minted server certificate in
servercert.pem
. The private key was created earlier and is available inserverkey.pem
.Finally, you can inspect your freshly minted certificate with the following:
Earlier, you added the following to
CA_default
:copy_extensions = copy
. This copies extension provided by the person making the request.If you omit
copy_extensions = copy
, then your server certificate will lack the Subject Alternate Names (SANs) likewww.example.com
andmail.example.com
.If you use
copy_extensions = copy
, but don't look over the request, then the requester might be able to trick you into signing something like a subordinate root (rather than a server or user certificate). Which means he/she will be able to mint certificates that chain back to your trusted root. Be sure to verify the request withopenssl req -verify
before signing.If you omit
unique_subject
or set it toyes
, then you will only be allowed to create one certificate under the subject's distinguished name.Trying to create a second certificate while experimenting will result in the following when signing your server's certificate with the CA's private key:
So
unique_subject = no
is perfect for testing.If you want to ensure the Organizational Name is consistent between self-signed CAs, Subordinate CA and End-Entity certificates, then add the following to your CA configuration files:
If you want to allow the Organizational Name to change, then use:
There are other rules concerning the handling of DNS names in X.509/PKIX certificates. Refer to these documents for the rules:
RFC 6797 and RFC 7469 are listed, because they are more restrictive than the other RFCs and CA/B documents. RFC's 6797 and 7469 do not allow an IP address, either.