Table of Contents

Create Internal CA

This is the Certificate of Authority. This will be used to validate all of the later certificates you create. You will be putting part of the CA into each and every one of your machines, saying “anything signed by this is valid.”

The premier thing here is security. You will be creating a certificate that will tell everyone connecting “hey, I vouch for this web site, whatever. I trust it, it is really what it says it is.”

This is controlled through your private key, and whatever password you put on it. Anyone who has access to those two things, and can do a little DNS poisoning, can totally own you.

Large companies, like Let's Encrypt, or Thawte, or whatever, are set up so it takes three or four people, together, to get access to the CA.

At Daily Data, the password is available to the owner and the senior technician (who has worked for the company over 20 years). The private key is stored in three secure locations, and the password is written down in our company's safe deposit box.

Hope I've made it clear. Think security, especially if you are something other than an individual or a Mom and Pop (and even then, think security).

Since I work for Daily Data, I'll use that to create the names below. We have a server that has limited access and is generally turned off, and I'll use that machine. It is a Linux machine, so I'll create a directory structure under /opt.

Quick and Dirty

Ok, these instructions are just a guideline. More details follow.

# create a little directory tree. 
# Not required, but allows the certs to be kept organized
mkdir -p /opt/localCert/newcerts
mkdir -p /opt/localCert/private
# this will store the indicies. Again, not required
touch /opt/localCert/DailyDataCAindex
cd /opt/localCert
# create a random rsa key pair of 2048 bits and ask for encryption passphrase (min 8 char)
openssl genpkey -algorithm RSA --outform PEM --des3 --out DailyDataCA.key --pkeyopt rsa_keygen_bits:2048
# Create a CA certificate from it. You'll need to answer a bunch of questions here
# see "create a config file" to keep from having to do that.
openssl req -x509 -new -key DailyDataCA.key -sha256 -days 3650 -out DailyDataCA.crt

Details

Create the private key

The following command will generate the private key for your CA. I have used \ to make it multi-line (it is all one command, so make sure no spaces after the \'s)

openssl \
   genpkey \
   -algorithm RSA \
   --outform PEM \
   --des3 \
   --out DailyDataCA.key \
   --pkeyopt rsa_keygen_bits:2048

When run, it will generate a 2048 bit private key, then ask you for a passphrase (then again to verify). Here is a breakdown of the parameters:

Note: you can use the -pass parameter to accept the password from a file (or stdin). See the options in the Pass Phrase Options of man 1 openssl on unix machines

Note: you do not have to use a password if you can ensure the key is secure at all times. Simply remove -des3 from the command.

Note: The old way of generating keys was to use the command

openssl genrsa -des3 -out DailyDataCA.key 2048

but that has been supercseded by genpkey.

Create a configuration file

By creating a configuration file, you can bypass a lot of redundant questions and answers when generating certificates. I name it openssl.cnf and place it in the directory with my CA files. The following is not correct at this time (stil working on the documentation).

openssl.cnf
# this section is for requests
[ req ]
default_bits           = 2048 # make all private keys 2048 bits (default)
default_md             = sha256 # use sha256 (default)
prompt                 = no  # do not ask any questions you don't have to
distinguished_name     = req_distinguished_name # section where DN information stored
 
# section holds Distinguished Name fields so we don't have to enter them all the time
# Instead of abbreviations used below, may also use 
# commonName, countryName, localityName, organizationName, organizationalUnitName, stateOrProvinceName
[ req_distinguished_name ]
C                      = GB
ST                     = Test State or Province
L                      = Test Locality
O                      = Organization Name
OU                     = Organizational Unit Name
CN                     = Common Name
emailAddress           = test@email.address
 
# used when generating certificate of authorities (ca)
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = critical, CA:true

Create the CA Cert

Now that you have a private key, we can use that to create a certificate to be used to sign the certificates. The file created (with a .pem suffix) will also be added to each device that needs to access certificates generated. So, for example, workstations where people are accessing internal web sites which will have certificates signed by the CA.

openssl \
   req \
   -x509 \
   -new \
   -key DailyDataCA.key \
   -sha256 \
   -days 3650 \
   -config openssl.cnf \
   -reqexts v3_ca \
   -out DailyDataCA.pem

This will read the key file (.key) and generate a certificate from it. Parameters are:

Modify openssl.cnf

[ 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