A service of Daily Data, Inc.
Contact Form

User Tools

Site Tools


software:openssl:createcert

This is an old revision of the document!


Create Service Certificate

I use the term “Service Certificate” here since we are attaching a certificate to a service, be it a web server running Apache or an sftp server using openssh.

On our workstations, we installed the Certificate of Authority (CA) at a very low level, so all services could use that to validate remote services. On our servers, we will install Certificates, signed by that CA, to validate that a service is really the one you think it is.

Doing this requires building a certificate, signing it with our CA, then exporting it to the server whose service we want to validate. An example would be an Apache web service, where we might put the certificate into a directory, then modify the Apache configuration to use that certificate for SSL sessions (ie, using https).

Creating the Certificate

Creating the certificate is similar to creating a CA: We create a key file, then turn it into a certificate. The difference is, as an intermediate step, we create a CSR (Certificate Request) which uses the key, then we use that to create and sign the certificate with the CA. The basic functionality is shown in the following four steps.

  1. Create an EXT (extension) file containing the names which the service will be called by.
  2. Generate a private key
  3. Create a signing request
  4. Generate the certificate and sign them with the CA

We'll take each one in turn, then I'll show you a simple script that can automate the process.

Create EXT file

The EXT file defines how to create the cert and what services it is valid for. You can have one or more names which the certificate is valid for. For example, if a web server can be called as web.example.local, or simply web, you would want both. If you want the same certificate to also handle mail.example.local, you could add that. And, in some cases, it is advantageous to include the IP address(es) of the server it is on.

An EXT file is a lot like a openssl.cnf file, but with some additional stanzas. To simplify things, I tend to copy the openssl.cnf file to a new file name, then add the additional stanzas, then use the same file for both.

Here is an example of an ext file which has been merged with an openssl.cnf file to allow it to be used for both functions.

[ req ]
default_bits       = 2048 # default key size
default_md         = sha256 # default message digest algorithm
distinguished_name = req_distinguished_name # definition used for DN
req_extensions     = v3_req # go look at v3_req section for the extensions def
prompt             = no # do not ask questions, take defaults
 
[ req_distinguished_name ]
# Required fields
CN = www.example.com
# not required
C  = US
ST = Texas
O  = Example Corp
L  = Dallas
OU = Headquarters
emailAddress = info@example.com
 
[ v3_req ]
keyUsage          = critical, digitalSignature, keyEncipherment
extendedKeyUsage  = serverAuth, clientAuth
subjectAltName    = @alt_names # look for section [ alt_names ] for all the names
basicConstraints  = CA:FALSE
 
[ alt_names ]
DNS.1 = www.example.local
DNS.2 = example.local
DNS.3 = mail.example.local
DNS.4 = 192.168.1.1

Here, we've added prompt = no to tell openssl to not prompt us for values, but instead use what is in the ext file if possible. We have also added req_extensions = v3_req to tell it to go look in the stanza labeled v3_req for some additional information.

In the [v3_req] stanza, we tell what this key will be used for (critical, digitalSignature, keyEncipherment), tell it the extendedKeyUsage (serverAuth, clientAuth), and add a basicConstraint of CA:FALSE, meaning this is not a Certificate of Authority.

Finally, we give it subjectAltName, which points to another stanza where we will list one or more names the certificate will be responsible for.

In the alt_names, we list multiple DN (alternate names). The format is DNS=URL But, since openssl configuration files can not list the same key more than once, we modify it slightly by adding arbitrary text after a period. openssl will ignore anything between the period and the equals sign, so we just list them as DNS.1=name DNS.2=alias DNS.3=another alias

This is used when we build a Certificate Request and then integrated as alternate names in the subject for the DN.

I save this file as name (the primary name of the service) with an extension of .ext

Generate Private Key

Private key generation is the same as it was for the CA, except we do not want a password in most cases. If we have a password, it would require you to enter the password every time a service was restarted.

Create CSR (Request)

Generate Certificate and sign

[ ca ]
default_ca = CA_default
 
[ CA_default ]
dir               = ./myCA              # Location of the CA certificate and private key
database          = $dir/myCAindex      # Database index file
new_certs_dir     = $dir/newcerts       # Directory where new certs are stored
certificate       = $dir/ca.crt         # The CA certificate
private_key       = $dir/ca.key         # The CA private key
default_md        = sha256              # Default digest method
preserve          = no                  # Keep existing certificates (yes/no)
policy            = policy_any          # Default policy for issuing certificates
 
[ policy_any ]
countryName             = optional
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = required
emailAddress            = optional
# create private key
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048
# create certificate for private key
openssl req -new -key server.key -out server.csr
# sign with CA (see configuration)
openssl ca -in server.csr -out server.crt -config openssl.cnf
# view cert
openssl x509 -in server.crt -text -noout
software/openssl/createcert.1760926803.txt.gz · Last modified: 2025/10/19 21:20 by rodolico