Summary: Need to create X.509 certificate chain? This post explains how to do it with OpenSSL commands and gives minimal working examples of the configuration for typical test/demo cases.
A config file is needed
OpenSSL commands (that is, the ones invoked from the command line) are mostly
controlled by their options. But in order to issue X.509 certificates or CSRs
OpenSSL needs a configuration file.
This file may contain no useful information, but is still required.
This post gives and explains minimal configuration files for OpenSSL commands
used for certificate generation:
OpenSSL installation should supply a default configuration file,
Below, we'll use expressions
openssl.cnf and "OpenSSL configuration file"
The topic of this post is the minimal configuration file. Sometimes the command will need more parameters than such minimum contains; in these cases they will be provided via command-line options. These options are kept at minimum too, so in real applications you'd likely need to pass more parameters - either via the config file or through the options.
Let's proceed to creating the certificate chain, i.e. one CA certificate and one "leaf" certificate issued by the CA.
Generate the private key
Generation of the private key can be included in some of the commands below,
but for clarity let's create a private key with a separate command.
To sound modern, pick an elliptic curve
openssl ecparam -list_curves with the name which sounds cute,
(on a serious note - selection of the elliptic curve is out of scope
of this post):
$ openssl ecparam -genkey -name secp521r1 -out privkey.pem
We'll use this same key for all certificates which appear later; of course such practice is acceptable only for demonstration or testing.
Create a self-signed CA certificate
This command needs a config file. Unless one is provided, OpenSSL will use the default, which may not contain what you want. There are two ways to provide a custom config:
We'll use the first way to show the config file in a more explicit manner.
There are two OpenSSL subcommands which can be used to create a self-signed
req -x509 and
ca. Examples of both are below.
Using "req -x509" command
The minimum config file for this command is:
[ req ] distinguished_name = req_dn [ req_dn ]
Call this file
With it, you can issue self-signed certificates:
$ openssl req -new -x509 -nodes -key privkey.pem -config openssl-min-req.cnf -subj "/CN=My self-signed CA certificate" -out ca.pem
If we do not specify the version explicitly or request any of X.509v3 extensions, then OpenSSL sets the version the certificate to 1.
openssl x509 -purpose -in ca.pem and
observe that various "CA" purposes come with
Yes (WARNING code=3).
Surprisingly, for a V3 certificate, there seems to be no clear indication
whether it is a CA certificate or not. Two extensions claim properties
related to CA functionality. OpenSSL's C API function
returns non-zero when the certificate either has
basicConstraints extension, or
Other software may follow other rules (for example, require
To satisfy OpenSSL's interpretation, the minimal
openssl.cnf can be
[ req ] distinguished_name = req_dn x509_extensions = v3_ext [ req_dn ] [ v3_ext ] basicConstraints = CA:true
Using "ca -selfsign" command
Below is the minimal
openssl-ca.cnf which would do the job.
[ ca ] default_ca = CA_default [ CA_default ] database = index.txt serial = serial.txt policy = policy_default [ policy_default ]
For this command to succeed, three files referenced above must be created:
$ touch index.txt index.txt.attr $ echo '01' > serial.txt
When done, self-signed CA certificate is created with this command:
$ openssl ca -config openssl-ca.cnf -selfsign -in csr.pem -keyfile privkey.pem -md default -out ca.pem -outdir . -days 365 -batch
Now we have the CA certificate. Next, create leaf certificates signed by it.
Create a certificate signed by your new CA
Create a CSR
A CSR (Certificate Signing Request) is made with
For it, the "minimum request openssl.cnf" is sufficient:
$ openssl req -new -config openssl-min-req.cnf -key privkey.pem -nodes -subj "/CN=Non-CA example certificate" -out csr.pem
Inspect the CSR with
openssl req -text -noout -in csr.pem.
Having a CSR, the corresponding certificate can be issued using either
ca commands. Below are examples for both.
Sign the CSR using "x509 -req" command
$ openssl x509 -req -in csr.pem -CA ca.pem -CAkey privkey.pem -CAcreateserial -out cert.pem
x509 command seems to have no option
-config, but it honors the
OPENSSL_CONF. If the file is not readable, OpenSSL prints
WARNING: can't open config file: /usr/lib/ssl/openssl.cnf
and continues. For the example above, config file is not needed;
and if it is not needed, you should not use it, because it may bring in
items which you do not want. It looks like the way to "disable" config file
processing is to set
Sign the CSR using "ca" command
openssl-ca.cnf works also for this case, and cannot
$ openssl ca -config openssl-ca.cnf -cert ca.pem -keyfile privkey.pem -in csr.pem -out cert.pem -outdir . -md default -days 365 -batch
By default the
ca command does not copy the X.509v3 extensions from the
CSR (the ones specified in
x509_extensions section of the
[ req ] part
in our example
openssl-min-req.cnf) to the signed certificate.
To do so, add
copy_extensions = copy line to the CA section
[ CA_default ] in our example
Alternatively, the CA may add own extensions when signing a CSR -
for example, set
These should be listed in the section with the name given by the variable
x509_extensions in the
[ CA_default ] section.
- To create certificate chains with OpenSSL, a configuration file is needed.
- OpenSSL will use the default config file unless you provide another one
via command-line option or an environment variable.
- Except that
x509 -reqis missing the option.
- Except that
- While the default may work for some cases, if you need any control over your certificates, you'll need to create the config file.
- You get more control over the content of your certificates when starting with the bare minimum than with the default. The minimal examples are provided in this post.