In today’s digital landscape, securing communications and data integrity is paramount. One of the foundational elements of this security is the use of certificates, which are often issued by a Certification Authority (CA). While there are many commercial and open-source CAs available, sometimes you need a simple, custom solution for internal use or testing purposes. In this article, we’ll explore how to create a simple CA using a Bash script and OpenSSL, a robust open-source toolkit for SSL/TLS.
Prerequisites
Before we begin, ensure you have the following:
- A Unix-like operating system (Linux, macOS, etc.)
- OpenSSL installed (version 1.1.1 or later is recommended)
- Basic knowledge of Bash scripting
Step-by-Step Guide
Step 1: Set Up the Directory Structure
First, create a directory structure to store your CA files:
mkdir -p ~/myCA/{certs,crl,newcerts,private}
chmod 700 ~/myCA/private
touch ~/myCA/index.txt
echo 1000 > ~/myCA/serial
This structure will help organize your CA’s certificates, private keys, and other necessary files.
Step 2: Create the OpenSSL Configuration File
Create an openssl.cnf
file in the ~/myCA
directory with the following content:
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ~/myCA
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
private_key = $dir/private/ca.key.pem
certificate = $dir/certs/ca.cert.pem
crlnumber = $dir/crlnumber
crl = $dir/crl.pem
crl_extensions = crl_ext
default_crl_days = 30
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict
[ policy_strict ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
[ req_distinguished_name ]
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
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ crl_ext ]
authorityKeyIdentifier=keyid:always
Step 3: Generate the CA’s Private Key and Certificate
Run the following commands to generate the CA’s private key and self-signed certificate:
openssl genrsa -aes256 -out ~/myCA/private/ca.key.pem 4096
chmod 400 ~/myCA/private/ca.key.pem
openssl req -config ~/myCA/openssl.cnf \
-key ~/myCA/private/ca.key.pem \
-new -x509 -days 7300 -sha256 -extensions v3_ca \
-out ~/myCA/certs/ca.cert.pem
chmod 444 ~/myCA/certs/ca.cert.pem
You’ll be prompted to enter information for the certificate’s distinguished name (DN). Ensure that the information matches the policy defined in the openssl.cnf
file.
Step 4: Create a Bash Script for Automation
To streamline the process of issuing certificates, create a Bash script named issue_cert.sh
:
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <common_name>"
exit 1
fi
COMMON_NAME=$1
openssl genrsa -out ~/myCA/private/$COMMON_NAME.key.pem 2048
chmod 400 ~/myCA/private/$COMMON_NAME.key.pem
openssl req -config ~/myCA/openssl.cnf \
-key ~/myCA/private/$COMMON_NAME.key.pem \
-new -sha256 -out ~/myCA/csr/$COMMON_NAME.csr.pem \
-subj "/C=US/ST=State/L=Locality/O=Organization/CN=$COMMON_NAME"
openssl ca -config ~/myCA/openssl.cnf \
-extensions server_cert -days 375 -notext -md sha256 \
-in ~/myCA/csr/$COMMON_NAME.csr.pem \
-out ~/myCA/certs/$COMMON_NAME.cert.pem
chmod 444 ~/myCA/certs/$COMMON_NAME.cert.pem
Make the script executable:
chmod +x issue_cert.sh
Step 5: Issue a Certificate
To issue a certificate for a specific common name, run the script:
./issue_cert.sh example.com
This will generate a private key and a signed certificate for example.com
.
Conclusion
You’ve now set up a simple Certification Authority using a Bash script and OpenSSL. This setup is suitable for internal use, testing, or educational purposes. For production environments, consider using more robust solutions like Let’s Encrypt or other established CAs.