Semi-automatic Creation of CA and Application Certificate

Keywords: OpenSSL Database crontab Web Server

1 Overview

       The reason why this paper calls it semi-automation is that the application for certificates is not a routine work, but only a period of time. At the same time, when creating certificates and method certificates, some parameters need to be adjusted according to the user's needs, such as the validity time of certificates, and whether to encrypt private keys, etc., because the script is set to semi-automation, and some parameters need to be input manually. Parameters to reach the user's needs. Of course, if the environment is fixed, the parameters are fixed, and the effective time is fixed, the script with crontab can also achieve automated applications and issuance operations.

       CA center is also called CA organization, namely Certificate Authority, or Certificate Authority. This article will introduce how to create root CA, sub-CA, certificate application, certificate issuance and revocation certificate through openssl.

2 Concept

2.1 Creating Private CA s

The configuration file of openssl: / etc/pki/tls/openssl.cnf. The relevant configurations in this configuration file, such as certificate information matching strategy, certificate-related file saving path and naming are all stipulated here. This article will be attached to the introduction of some important parameters of the configuration file at the end of the article.

There are three certificate information matching strategies: matching, supporting and optional.

Matching means that the information required to fill in the application must be consistent with the CA settings. Support means that the application information must be filled in, optional means optional or not.

After the user generates the certificate request file on his own machine, he sends the corresponding request file to the server. After the server receives the request file, it confirms that it is correct and issues the certificate to the application host.

2.2 Certificate Application Procedures

There are four steps to apply for a certificate

a. Generation of application requests

Created by the client itself, the generated files are sent to the certificate issuing authority after completion.

b. RA verification,

RA(Registration Authority), the digital certificate registration and approval authority. RA system is an extension of CA certificate issuance and management. It is responsible for information entry, audit and certificate issuance of certificate applicants (security audit). At the same time, the corresponding management function (safety management) is completed for the issued certificates.

c. CA sign

After the verification is passed, the certificate is generated in the CA server 

d. Acquisition of certificates

Send the completed certificate to the applicant

3. Experimental steps

3.1 Create Root CA

3.1.1. Create the required files
touch /etc/pki/CA/index.txt 
# Generating Certificate Index Database Files
echo 01 > /etc/pki/CA/serial 
# Specify the serial number of the first certificate issued

3.1.2 CA Self-Visa

You have to have a private key before you can issue a certificate to yourself.

Generate the private key, the file name is fixed, and the directory is also the current fixed directory, because the path and name are specified in the configuration file.

cd /etc/pki/CA/


The following steps will generate encrypted files in the directory

(umask 066; openssl  genrsa-out  /etc/pki/CA/private/cakey.pem  -des 3  2048)

Generate self-signed certificate and sign it to yourself, -x509 is the key word, which means you have to apply for it and issue certificate to yourself.

Here the path of the file is required, the following to enter the password

openssl  req -new -x509 -key  /etc/pki/CA/private/cakey.pem   -days 7300 -out  /etc/pki/CA/cacert.pem

To enter a password, then submit information

- New: Generate a new certificate signing request

- x509: Special for CA to generate self-visa

- key: The private key file used to generate the request

- days n: validity period of certificate

-out / PATH/TO/SOMECERTFILE: Certificate Preservation Path

3.2 Create subCA

Creating Private Key and Certificate Request Files on 3.2.1 SubCA

The method and root CA are basically the same.

stay / Create serial and index.txt under etc/pki/CA


The following encryption des3, if encrypted, each method must enter a password


As a sub-CA, you can't issue certificates to yourself. You need to apply for certificates from root CA without x509 option.

Generate the subca.csr file and copy it to the directory / etc/kpi/CA / corresponding to the server root CA

3.2.2 Certificates are issued to sub-CAs on root CA

Here, the password is added to the root private key, so all of them need to enter the password before entering the information.


Generate the file subca.crt and copy it to subCA. Note that when this file is copied to subCA, the name should be changed to

Only cacert.pem can be used as the private key of the server to sign and issue to the client. 

At this point, the server-side root CA operation is completed, and the CA can issue certificates to other clients.

3.2.3 Verification

Find a machine and apply for a certificate from the sub-CA


Generate the request file, and the options entered here should be consistent with the configuration file policy of the root CA


When completed, send the request file to the subCA

This operation is described in 3.3.


3.2.4 Sub CA issues certificates to clients

The recommended certificate documents are placed in a unified directory. The first certificate issued is from serial 01.

openssl  ca -in rhel5.csr -out certs/rhel5.crt -days 300

The following errors occurred, some of which were strange. They were all henan, but they were still errors, because the version of openssl on client version 5 was inconsistent with that on sub-CA.

Causes incompatibility. Solution issuance is to upgrade the version of openssl to the same version



3.3 Certification

3.3.1 Generate certificate requests on hosts requiring certificates

Generate a private key for the web server. The name test.key can be named by itself, but the suffix cannot be. 2048 is the length.

(umask066; openssl   genrsa-out /etc/pki/tls/private/test.key  2048)

Generate certificate application file, use private key to generate request file, suffix is generally recommended for csr, and server generation is basically the same, less Keyword - x509, that is not self-signature, but application certificate

  - days 365 application time, this time is meaningless, because it is specified by the server when issued, the client specified time is meaningless.

openssl  req  -new -key /etc/pki/tls/private/test.key -days 365 -out /etc/pki/tls/test.csr

The request file name (key name) here is different by default each time. If you want to run, you need to change yes in index.txt.attr to no.

There is no encrypted des in the private key file, so unlike the server, you don't need to fill in the password after returning to the car, you just need to fill in the information after returning to the car.

National, provincial, and corporate matches are specified in the configuration template, so they should be the same as server-side matches.

3.3.2 Send request file to CA

Transfer the certificate request file to CA, which can be copied to the corresponding path on the server side with scp

3.3.3CA signs the certificate and issues it to the requester

 - days 365 The time specified here is the validity period. How long does it take for the client to be valid? No default is the time set by the service profile.

The field commonName = supplied is supplied. If the commonName of the new certificate request information is the same as the previous request information, then when the certificate generated by the previous request information has not been revoked, the new certificate will no longer be generated, generating 0 byte files.

openssl  ca -in /tmp/test.csr -out /etc/pki/CA/certs/test.crt -days 365

Send the certificate file back to the client after completion

3.4 Revocation of certificates

When an exception occurs to the client, the server can revoke the certificate

3.4.1 Series of certificates to be revoked at the client

openssl  x509 -in /PATH/FROM/CERT_FILE  [-noout|-serial|-subject]

3.4.2 Cancellation on CA

According to the serial and subject information submitted by the customer, the comparison test is

If the information in the index.txt file is consistent, revoke the certificate:

This step operates on the CA service and the certificate status is R after revocation.

openssl  ca -revoke /etc/pki/CA/newcerts/SERIAL.pem

After revocation, this information should be released. The client knows which certificates have been revoked

3.4.3 Specify the number of the first revoked certificate

Operating on the server root CA

crlnumber certificate revocation list number, you can see the status of Certificate in index.txt file

echo 01 > /etc/pki/CA/crlnumber

/ Digital representations saved in etc/pki/CA/crlnumber

The next certificate to be revoked is the number of certificates. If five certificates have been revoked, the current file is kept at 06, indicating that the sixth certificate will be revoked next.

Note: This statement does not need to be executed until the certificate revocation list is updated for the first time. If the certificate has been revoked before, this statement does not need to be executed.

3.4.4 Update Certificate Revocation List

Publish this document on the official website to let all users know that the certificate has been revoked

openssl ca  -gencrl  -out  /etc/pki/CA/crl/crl.pem

3.4.5 View crl files

Executing the following statement for viewing is not a necessary step

openssl crl -in  /etc/pki/CA/crl/crl.pem -noout  -text

4-half automated script

The following script will implement the above five steps, in order to facilitate the demonstration, the operation will be written in the same script. Operate the corresponding operation through options.

Users only need to input relevant operations to complete CA construction and certificate application, issuance, revocation and other operations.

The script is as follows

#!/bin/bash
#
#******************************************************************************
#Author:               Sunny
#Date:                 2017-09-09
#FileName:             install_ca.sh
#version:              1.0
#Your change info:     
#Description:          For auto create CA,subCA,generate and revoke cert
#Copyright(C):         2017  All rihts reserved
#*****************************************************************************

CApath=/etc/pki/CA
certpath=/etc/pki/CA/certs
tlspath=/etc/pki/tls
tlsprivatepath=/etc/pki/tls/private
caprivatepate=/etc/pki/CA/private


#check certification info,run below cmd
#openssl x509 -in cent7bbaa.crt -noout -text

#check certification request infomation,run cmd as below
#openssl req -noout -text -in aa.csr

#check certification status,run cmd as below,01 is serial number
#openssl ca -status 01



active_ip(){
actip=$(ip a| grep -E "[0-9]+\/"| cut -d / -f1|sed -nr  's@.*( [0-9]+\.[^0][0-9]*\.[0-9]+\.[0-9]+)@\1@p'|cut -d " " -f2|head -1)
}

pri_key_name(){
echo "private key name should end with .key,such as clent.key"
read -p "enter your private key name(default:client."$actip".key) " prikey
if [ -z ${prikey:-} ];then
prikey=client."$actip".key
fi
}

cli_csr_name(){
echo "Cert request name should end with .crs,such as clent.csr"
read -p "enter your cert request name(default:client."$actip".csr) " clicsr
if [ -z ${clicsr:-} ];then
clicsr=client."$actip".csr
fi
}

key_length(){
echo "key length should be one of 1024,2048,4096"
read -p "enter your private key length(default:2048): " length
if [ -z ${length:-} ]; then
length=2048
fi
}


root_pre(){

[ -e "$CApath"/index.txt ] || touch  "$CApath"/index.txt
[ -e "$CApath"/serial ] || echo 01 >  "$CApath"/serial
#create a server private key
echo "unless you have modify ca private key name in /etc/pki/tls/openssl.cnf,only use default cakey.pem"read -p "enter your ca private key name accord to openssl.cnf (default:cakey.pem) " cakey
if [ -z ${cakey:-} ];then
cakey=cakey.pem
fi
key_length
if [ -e "$caprivatepate"/"$cakey"  ] ;then
echo "The server already have private key,$cakey, under "$caprivatepate"/,please check"
else
umask 066;
read -p "enter yes to encrypt private key,other enter will no enrypt: " yorn
if [ "$yorn" = yes ];then
   read -p "enter encrypt key word(eg:-des3): " encry
   openssl genrsa -out "$caprivatepate"/"$cakey" "$encry" "$length"
   else
    openssl genrsa -out "$caprivatepate"/"$cakey"  "$length"
fi
umask 022;
fi

}



echo "Enter 1 : run at root CA server and rootca_sig_itself"
echo "Enter 2 : run at sub_server,generate a private key and signature request file,and send request file to root CA "
echo "Enter 3 : run at client host,generate certification requst file and send to server auto"
echo "Enter 4 : run at server,generate certification and send to client auto"
echo "Enter 5 : run at server,to revoke some certification"
read -p "Please input your choice: " choice

case $choice in

1)

root_pre;

#generate a signature certificate for itself,-x509 is key work,means it signature to itself
echo "unless you have modify ca  signature certificate name in /etc/pki/tls/openssl.cnf,only use default cacert.pem"
read -p "enter your ca signature cer name accord to openssl.cnf (default:cacert.pem) " cacert
if [ -z ${cacert:-} ];then
cacert=cacert.pem
fi
if [ -e "$CApath"/"$cacert"  ] ;then
 echo "The server already have signature certificate,"$cacert" under "$CApath",please check"
 else
openssl  req -new -x509 -key "$caprivatepate"/"$cakey"   -days 7300 -out  "$CApath"/"$cacert"
fi
;;

2)

root_pre;
#generate a signature certificate request file and send to root CA
read -p "enter your ca signature cer request file  (default:subca.csr): " subcacert
if [ -z ${subcacert:-} ];then
subcacert=subca.csr
fi
if [ -e "$CApath"/"$subcacert"  ] ;then
 echo "The sub ca already have signature certificate,"$subcacert"under "$CApath",please check"
 else
openssl  req -new  -key "$caprivatepate"/"$cakey"   -days 7300 -out  "$CApath"/"$subcacert"
fi

#send request file to root CA
read -p "which root CA would you send(default:192.168.32.61): " serip
if [ -z ${serip:-} ];then
serip=192.168.32.61
fi
expect -c "
   spawn  scp   "$CApath"/"$subcacert"   root@"$serip":"$CApath"/certs/
   expect {
           \"*assword\" {set timeout 500; send \"Pass1234\r\"; }
           \"yes/no\" { send \"yes\r\"; exp_continue; }
    }
    expect eof"
;;

3)
echo "Please check whether you are in client"
#client generate private key
active_ip
pri_key_name
cli_csr_name
key_length


if [ -e "$tlsprivatepath"/"$prikey"  ] ;then
echo "The client already have private key "$prikey" under "$tlsprivatepat",please check"
else
umask 066;
if [ "$yorn" = yes ];then
   read -p "enter encrypt key word(eg:-des3): " encry
   openssl genrsa -out "$tlsprivatepath"/"$prikey" "$encry" "$length"
   else
    openssl genrsa -out "$tlsprivatepath"/"$prikey"  "$length"
fi
umask 022;
fi
#generate a signature certificate to root ca,without -x509.

if [ -e "$tlspath"/"$clicsr"  ] ;then
 echo "The client already have signature certificate request file,"$clicsr" under "$tlspath",please check"
 else
openssl req -new -key "$tlsprivatepath"/"$prikey" -out "$tlspath"/"$clicsr"
fi
#send request file to CA
read -p "which CA would you send(default:192.168.32.61): " serip
if [ -z ${serip:-} ];then
serip=192.168.32.61
fi
expect -c "
   spawn  scp  "$tlspath"/"$clicsr" root@"$serip":"$CApath"/certs/
   expect {
           \"*assword\" {set timeout 500; send \"Pass1234\r\"; }
           \"yes/no\" { send \"yes\r\"; exp_continue; }
    }
    expect eof"
;;
4)
read -p "enter which requst file in "$CApath"/certs you want want server to generate as certification(eg:cent7.csr): " clientrsq
read -p "enter new client cetification name(eg:cent7.crt): " crtname
[ -e "$CApath"/certs/"$crtname" ] && { echo $crtname exist,please check;exit 6; }
read -p "enter many days would the cert be avlid(eg:365): " days
if [ -e "$CApath"/certs/"$clientrsq" ];then
#attention,no only $crtname be generated,but also serial.pem file will be generate under dir newcerts

 openssl ca -in  "$CApath"/certs/"$clientrsq" -out "$CApath"/certs/"$crtname" -days "$days"
else
  echo "$clientrsq does no exist in "$CApath"/certs,please check"
fi

read -p "which client would you send(eg:192.168.32.61): " clip
expect -c "
   spawn  scp   "$CApath"/certs/"$crtname"  root@"$clip":"$tlspath"
   expect {
           \"*assword\" {set timeout 500; send \"Pass1234\r\"; }
           \"yes/no\" { send \"yes\r\"; exp_continue; }
    }
    expect eof"

;;
5)
read -p "Please input the serial number you want to revoke(eg:03): " sernum
echo "you can run cmd  openssl x509 -in cent7bt.crt -noout -text  to check the serial number,cent7bt.crt is the certification you want to revoke"
openssl ca -revoke /etc/pki/CA/newcerts/"$sernum".pem
crlnum=$(cat /etc/pki/CA/crlnumber)
[ -z $crlnum ] && echo 01 > /etc/pki/CA/crlnumber;
openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem;
#check the the crl list
#openssl   crl  -in /etc/pki/CA/crl/crl.pem  -noout  -text
;;


*)
  echo  "your input is wrong,please check"
  ;;
esac


unset ip
unset crtname
unset CApath
unset clinetsrq


5/etc/pki/tls/openssl.cnf

This appendix only notes some important fields in Chinese. The contents are as follows.

/etc/pki/tls/openssl.cnf 
CA Configuration file. This file is critical. Configuration and CA Closely related

[ CA_default ]  The name of the newly created file must be the same. If you want to change it, you must follow defaults equally

dir     = /etc/pki/CA       # Where everything is kept, CA working directory, CA information saved directory
                             #
certs       = $dir/certs        # Where the issued certs are kept, defining a variable
crl_dir     = $dir/crl      # Where the issued crl are kept, certificate revocation list
database    = $dir/index.txt    # database index file. This is a file that stores the certificate database, such as which certificates have been issued, certificate number, certificate status and other information. This file does not exist by default. It is necessary to create an empty file manually. When issuing certificates, it will be issued manually. If there is no empty file, it will report errors when issuing certificates.
#unique_subject = no            # Set to 'no' to allow creation of
                    # several ctificates with same subject.
new_certs_dir   = $dir/newcerts     # default place for new certs. Default place directory for new certificates. This file is automatically generated and numbered digitally
certificate = $dir/cacert.pem   # The CA certificate, CA's own certificate, root CA's own certificate, sub-CA's superior certificate
serial      = $dir/serial       # The current serial number, to be created manually, the current serial number, is a hexadecimal number, the actual meaning is the number of the next certificate, the default is from 00, you can specify the starting value, must be a hexadecimal number.
crlnumber   = $dir/crlnumber    # the current crl number, certificate revocation number, also refers to the number of the next certificate revoked, that is, the number of the next revoked certificate.
                    # must be commented out to leave a V1 CRL
crl     = $dir/crl.pem      # The current CRL
private_key = $dir/private/cakey.pem# The private key. CA's private key
RANDFILE    = $dir/private/.rand    # private random number file, random number

x509_extensions = usr_cert      # The extentions to add to the cert

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt    = ca_default        # Subject Name options, naming
cert_opt    = ca_default        # Certificate field options

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions    = crl_ext

default_days    = 365           # how long to certify for, the validity period of the certificate can be specified
default_crl_days= 30            # how long before next CRL, validity of CRL
default_md  = default       # use public key default MD
preserve    = no            # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy      = policy_match,The strategy is specified below to indicate the information that customers are required to provide when they apply for certificates.

# For the CA policy
[ policy_match ]  This is the default policy for the system
countryName     = match  Country, match It has to be matched. Both sides have the same information. The others can be different.
stateOrProvinceName = match  Province, match If not, they will refuse and will not issue certificates.
organizationName    = match  organization
organizationalUnitName  = optional department 
commonName      = supplied  Common names, such as domain names of Web servers, are usually strictly matched or can be written as pan-domain names, which are expensive to apply for.
emailAddress        = optional  ,Options, not mandatory

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ] For external use, no need match Options, not exactly the same
countryName     = optional
stateOrProvinceName = optional
localityName        = optional
organizationName    = optional
organizationalUnitName  = optional
commonName      = supplied
emailAddress        = optional

[ req ]
default_bits        = 2048
default_md      = sha1
default_keyfile     = privkey.pem
distinguished_name  = req_distinguished_name
attributes      = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert

6 Summary

Because openssl is a powerful command with a large number of parameters, the parameters listed in this article are only a few parameters that must be used to generate very promulgated parameters. If more options are needed, users can add them themselves.






Posted by blanius on Sat, 25 May 2019 14:30:14 -0700