Skip to content

HOWTO generate certificates

This HowTo is inspired from openssl-certificate-authority

Why do that

You want to deploy LMC security components, some of them are based on HTTPS, so you will need to generate X509 certificates.

Prerequisites

  • Ensure openssl ( >= 1.0.1) is installed.

How to do

Two different ways are approachable by the user to generate certificates :

  • In standalone, use punchplatform-ssl-certs.sh -h to learn how to generate self-signed certificates or a full chain of certification easily
  • Use the manual way by writing the proper openssl configurations, directories and openssl commands

What to do

With punchplatform-ssl-certs.sh

Usage :

1
punchplatform-ssl-certs.sh [option] [optionnal: --pkcs8]

Description :

  • This script helps the user to create certificates and perform TLS handshake tests quite simply.
  • All generated keys and certificates will be placed inside $PUNCHPLATOFRM_CONF_DIR/resources/ssl
  • A full chain of certificates can be generated. According to the option given to punchplatform-ssl-certs.sh, the user can create the CA root certificate only, or the intermediate certificate signed by the CA, or both client and server certificates signed by the intermediate entity. See the following option section to learn more.
  • The generation of a chain will override the previous version.
  • Self-signed certificates can be generated using punchplatform-ssl-certs.sh --self-signed. A private key and a self-signed certificate are created and placed inside a self-signed folder.
  • Self-Signed certificates are created with a timestamp, so they don't override the previous versions of certificates.

Options :

Command Description
-h Print script usage
-m, --make Create all directories and files needed for key generation. Configure openssl for each part of the chain (ca, intermediate, client and server)
-p, --purge Delete all directories and files needed for key generation
-r, --root [--pkcs8] Generate CA root key and certificate. The user must provide a password and all needed information for the certificate ( locations, email, ...)
-i, --intermediate [--pkcs8] Generate CA root key and certificate then a CA chain with intermediate key and certificate
-a, --all [--pkcs8] Generate CA chain with CA root and intermediate certs, then keys and certs for a server and a client
--pkcs8 Toggle keys conversion to pkcs8 format when --root, --intermediate or --all options are used
--self-signed Generate a unique pair of a private key and a self-signed certificate
--reset Recreate directories. Same as --purge then --make

With manual installation

At the end of the procedure, you will have three certificates (and their associated private keys) :

  • CA (Certification Authority) certificate : it 's you root certificate, entity signing other certificates
  • Intermediate certificate : it 's an intermediate certificate, signed by CA and signing Applicative Server certificates
  • Applicative Server certificate : it 's the certificate associated to your applicative server (Apache for example)

Warning

This HowTo has not been written by a security expert, so even if attention has been paid on algorithms, keys size, etc, it may not respect best security principles. To generate certificates used in production, please consult a security expert.

1 . Create a CA (Certification Authority) directory

1
2
3
4
5
6
7
$ mkdir ~/ca
$ cd ~/ca
$ mkdir certs crl newcerts private
$ chmod 700 private
$ touch index.txt index.txt.attr
$ echo 1000 > serial
$ echo "unique_subject = yes" > index.txt.attr

2 . Create your CA openssl.cnf configuration file

In ca directory, create a file named openssl.cnf and fill it with following content. Be careful, section req _distinguished _name (country name, etc) has to be adapted to your context.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = .
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/ca.key.pem
certificate       = $dir/certs/ca.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 7500
preserve          = no
policy            = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = FR
stateOrProvinceName_default     = Paris
localityName_default            = Paris
0.organizationName_default      = TS
organizationalUnitName_default = TS
#emailAddress_default           =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
  1. Generate CA key & certificate
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ cd ~/ca
# It's your root CA certificate, potentially used for many years.
# So its private key has to be strong enough. Recommendation of ANSSI (french
# security agency) is to generate 4096-bits keys.
$ openssl genrsa -aes256 -out private/ca.key.pem 4096
$ chmod 400 private/ca.key.pem
# Generate self-signed certificate, valid for 7300 days (~ 20 years)
$ openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
# Check certificate seems correct using following command
$ openssl x509 -noout -text -in certs/ca.cert.pem
$ chmod 444 certs/ca.cert.pem
  1. Create intermediate directory
1
2
3
4
5
6
7
8
9
$ cd ~/ca
$ mkdir intermediate
$ cd intermediate
$ mkdir certs crl csr newcerts private
$ chmod 700 private
$ touch index.txt index.txt.attr
$ echo "unique_subject = yes" > index.txt.attr
$ echo 1000 > serial
$ echo 1000 > crlnumber
  1. Create your intermediate openssl.cnf configuration file

In intermediate directory, create a new file named openssl.cnf and fill it with following content. Be careful, section req _distinguished _name (country name, etc) has to be adapted to your context.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = .
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/intermediate.key.pem
certificate       = $dir/certs/intermediate.cert.pem

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/intermediate.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 7500
preserve          = no
policy            = policy_loose

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = FR
stateOrProvinceName_default     = Paris
localityName_default            = Paris
0.organizationName_default      = TS
organizationalUnitName_default = TS
#emailAddress_default           =

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
  1. Generate intermediate key & certificate
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ cd ~/ca
# Your intermediate certificate will potentially sign many certificates.
# It will be used for a long period too, so generate a strong private key (4096 bits).
$ openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096
$ chmod 400 intermediate/private/intermediate.key.pem
# Generate your signing request
$ openssl req -config intermediate/openssl.cnf -new -sha256 -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem
# Sign intermediate certificate with CA private key
$ openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
# Check certificate seems correct using following command
$ openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
# Check intermediate certificate has correctly been signed by CA
$ openssl verify -CAfile certs/ca.cert.pem intermediate/certs/intermediate.cert.pem
# Concatenate intermediate and ca certificate to generate a chain of certificates
$ cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
  1. Generate application server key & certificate
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ cd ~/ca
# Your applicative server (Apache for example) will be used only for one application,
# for a shorter period (10 years in our example). So recommendation is to use 2048-bits
# private keys. Generate in one command your private key and your signing request.
# Pay attention: we specified a subject with several server names.
# In our example names TSSOCFRP01P, TSSOCFRP02P and TSSOCFRP0AP
# respectively match to two identical Apache web-servers and the associated VIP (used
# in a High Availability context). Of course you have to adapt names.
$ openssl req -newkey rsa:4096 -keyout intermediate/private/apache.key.pem -days 3650 -out intermediate/csr/apache.csr.pem -subj "/C=FR/L=Paris/O=ts/OU=ts/CN=TSSOCFRP0AP.fo.prod-in.soc.ts/subjectAltName=DNS.1=TSSOCFRP0AP,DNS.2=TSSOCFRP01P,DNS.3=TSSOCFRP01P.fo.prod-in.soc.ts,DNS.4=TSSOCFRP02P,DNS.5=TSSOCFRP02P.fo.prod-in.soc.ts/emailAddress=soc@thalesgroup.com" -nodes
$ chmod 400 intermediate/private/apache.key.pem
# Sign certificate with intermediate private key
$ openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 3650 -notext -md sha256 -in intermediate/csr/apache.csr.pem -out intermediate/certs/apache.cert.pem
# Check application server has correctly been signed by intermediate private key
$ openssl verify -CAfile intermediate/certs/ca-chain.cert.pem intermediate/certs/apache.cert.pem