You can call us on +44 20 3337 3012 today to discuss your current challenges and how we can best help, or email us at help@hanscombe.net.

OpenSSL PKCS Guide

This guide summarises the most useful OpenSSL PKCS (Public Key Cryptography Standard) commands.

These commands use the PEM (Privacy Enhanced Mail) format, where either a key or certificate are stored as a delimited base64 string.

The below commands use 4096-bit RSA keys. These are not known to be compromised by quantum computing yet, but are likely to be over the next few years. This is believed to be sufficient for use-cases that involve the protection of transmitted data which holds value for less than a year and where threat actors are non-state-actors, this is believed to be sufficient. For data which holds value for longer, or may need protection from state-actors, we would recommend a hybrid solution which includes quantum-resistant ciphers, in case the data is collected and subsequently decrypted once RSA is defeated.

The following commands focus on RSA, rather than ECC-based cryptography, as it is currently believed to be less vulnerable to quantum attacks. It can also be less performant, so please perform your own testing where this is a factor.

The following commands also use SHA512. While SHA256 is adequately resistant to either classical or near-future quantum collision attacks, modern 64-bit processors should perform SHA512 well, and so dramatically increase the search space at little cost. Those using 32-bit processors or constrained hardware should perform their own tests.

RFC 5958 on Asymmetric Key Packages
RFC 7468 on the PEM format
RFC 4648 on base64 encoding
NIST project on Post-Quantum Cryptography
Open Quantum Safe project

Create a directory in which to store private keys

Private keys need to be kept secure, so we’ll create a directory to keep them in:

mkdir -p ~/.ssl/private
chmod 700 ~/.ssl/private

Create a key

Create a key without a passphrase:

openssl genrsa -out ~/.ssl/private/unprotected.pem 4096

Create a key with a passphrase:

openssl genrsa -aes256 -out ~/.ssl/private/protected.pem 4096

Generally, for applications where the certificate is used unattended (eg. for starting a webserver), the key is stored unprotected.

For applications where the certificate is used attended (eg. a CA key for signing other certificates), the password is stored protected. In this code example, we use AES256 to protect the key, rather than the deprecated triple-DES (3DES) standard.

Advanced use cases for unattended key use could include the generation of a key with a passphrase, that is stored separately from the key, and combined with the key within a well-defined cryptographic boundary.

RFC 5208 on PKCS, private keys including passphrases
NIST 3DES documentation
NIST notice to withdraw 3DES
RFC 3370 on Cryptographic Message Syntax (CMS), used for the passphrase
RFC 3565 including the object identifier (OID) for AES256

X.509 Certificate Subject DN Fields

X.509 certificates include a Subject DN (Distinguished Name), which is normally comprised of the below fields.

A Distinguished Name is a standard for expressing attributes, and in the case of an X.509 certificate subject, it contains the attributes of whatever the certificate refers to, be it a server (for server TLS certificates), a person (for client TLS certificates), or a certificate authority (for CA certificates). The data within these fields needs to be encoded in the UTF-8 character set.

The fields allowed within Public Certificate Authority-issued certificates are sometimes specific to the policies of each authority, and sometimes discussed more broadly at the CA/Browser forum (see link below).

Abbreviation Name Description
CN CommonName For server certificates, this should match DNS hostname of the server on which the certificate is to be used. For CA root certificates, it can be descriptive of the root CA.
L LocalityName A city, county or geographical area within which the head office of the organisation is located, though often not needed, and so not included.
ST stateOrProvinceName State or province in which the head office of the organisation is located.
O OrganizationName The full legal name of the organisation to which the certificate is issued.
OU OrganizationalUnitName Often indicates the department, cost centre, or project the certificate is used for. Cannot be included for certificates from Public Certificate Authorities.
C Country The alpha-2 country code for the country where the head office of the organisation is located.

For OpenSSL the subject DN can be expressed as a string, concatenating these fields into a forward-slash-separated string, normally in the above order, for example:

/CN=www.perfectapplepies.co.uk/ST=London/O=Perfect Apple Pies Ltd/OU=Marketing/C=GB/

RFC 4519 for Distinguished Name fields
ITU-T X.52O for X.509 fields
ISO Online Browsing Platform for ISO 3166-1 alpha-2 codes
CA/Browser Forum for CA requirements

Create a CA certificate

The following creates a private self-signed CA certificate for a fictitious company Fred James Ltd from the private key specified.

The key should be protected by a passphrase, in which case the following command will prompt for it:

mkdir -p ~/.ssl/private/ca/newcerts
openssl req -x509 -new -key ~/.ssl/private/protected.pem -sha512 -days 365                  \
            -out ~/.ssl/private/ca/ca.crt.pem                                               \
            -subj "/CN=Fred Jones Primary Trust CA/ST=London/O=Fred Jones Ltd/OU=IT/C=GB/"  \
            -addext keyUsage=keyCertSign                                                    \
            -addext basicConstraints=critical,CA:TRUE,pathlen:0

The -x509 option causes a self-signed certificate to be output rather than a CSR.

The extension specified with the first “-addext” parameter allows the certificate to be used to sign other certificates. The second “-addext” limits the CA path-length to specify how many CAs can exist below this one in the certification chain, and so in this case no intermediate CAs can be used.

The generated certificate (ca.crt.pem) can be distributed and installed on systems which should trust certificates signed by this ca.

The private key (protected.pem) should not be distributed, except possibly to back it up, and then only while using a secure passphrase, which is kept separate from the key, appropriate controls and key-handling rituals.

RFC 5280 on the pathlen constraint and keyCertSign keyUsage

Create CA Configuration

First find out what directory the default openssl.conf file should be in:

openssl version -d

For the Ubuntu distribution, this is /usr/lib/ssl, and the openssl.cnf file can be found at /usr/lib/ssl/openssl.cnf (it is actually symbolically linked from elsewhere, but that doesn’t matter). We can use the path from the version command to chain our own configuration:

touch ~/.ssl/openssl.cnf
chmod 700 ~/.ssl/openssl.cnf
cat <<EOF >~/.ssl/openssl.cnf
.include /usr/lib/ssl/openssl.cnf

[ CA_my ]
dir = ${ENV::HOME}/.ssl/private/ca
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/ca.crt.pem
serial = $dir/serial
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
private_key = ${ENV::HOME}/.ssl/private/protected.pem
default_md = sha512
name_opt = ca_default
cert_opt = ca_default
policy = policy_match

[ policy_match ]
countryName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
EOF
echo '00' >~/.ssl/private/ca/serial  # initialise serial number
touch ~/.ssl/private/ca/index.txt    # create index

The first part of the configuration specifies where all of the CA files are to be kept, with a .include statement to chain this to the distribution configuration file.

The cert_opt and name_opt commands then control how the CSR details are displayed at the time of the signing.

The latter part of this configuration gives the CA policy:

Keyword Description
match Must match the equivalent value in the CA certificate.
optional Can be supplied, but optional, not mandatory.
supplied Must be supplied.

Note, in this case we’re enforcing a match between the CA and requested certificate for the countryName and organizationName, ensuring that there is always a commonName as part of the CSR, and also allowing an optional organizationalUnitName and emailAddress.

Finally we initialised the serial and index files.

OpenSSL CA Options

Create a CSR

The following creates a certificate request:

openssl req -new -key ~/.ssl/private/unprotected.pem -sha512                      \
            -out ~/.ssl/server.csr.pem                                            \
            -subj "/CN=www.fredjones.com/ST=London/O=Fred Jones Ltd/OU=IT/C=GB/"  \
            -addext keyUsage=digitalSignature,keyEncipherment                     \
            -addext extendedKeyUsage=clientAuth,serverAuth

The digitalSignature and keyEncipherment keyUsages are needed for an RSA server certificate, as is the serverAuth extendedKeyUsage. The clientAuth extendedKeyUsage is added so that the certificate can be used for mutual TLS if needed.

CA Browser Baseline Requirements for the Issuance and Management of Publicly‐Trusted Certificates for keyUsage

Sign a CSR

A certificate request can be signed using the following command:

openssl ca -config ~/.ssl/openssl.cnf  \
           -name "CA_my"               \
           -days 365                   \
           -notext                     \
           -in ~/.ssl/server.csr.pem   \
           -out ~/.ssl/server.crt.pem

This command gives both the configuration file and the section to use, as we have created above.

The relevant certificate details will be displayed, and the signing will need to be confirmed, and the passphrase provided.

It is worth bearing in mind that the OpenSSL CA commands were originally intended as a reference implementation, showing how CA functions could be implemented, rather than as a fully-functional or easy to use piece of software.

openssl ca command documentation
openssl genrsa command documentation
openssl req command documentation
openssl rsa command documentation
OpenSSL configuration file format
Other OpenSSL command documentation
OpenSSL official Github repository


We're here to help

You can call us on +44 20 3337 3012 today to discuss your current challenges and how we can best help, or email us at help@hanscombe.net.