Be your own CA...
I have been running my own Certificate Authority (CA) for my systems for some time now. While running my CA is nothing like running a large commercial CA, running a personal CA is surprisingly easy.
Background
When I first got started with becoming my own CA, it was in the early 2000's and the tools out there were nonexistent. There was basically just openssl and the command line.
This was well before things like Lets Encrypt existed and the only place to get certificates was to pay for them. I recognize the landscape is different now (in 2026) but some of my reasons are even more important now than they were then.
My main reason for running my own CA was I didn't want to be forced to trust an external authority for my systems. Have you looked at the list of Certificate Authorities you browser and/or OSes trust by default? Fully trust. By default. Have a look, read through the names. I'm sure that 95% of these CAs you have never heard of, yet they are fully trusted. Any certificate issue by them for ANY domain will be fully trusted. I had a problem with this.
My original goal was to be able to create a certificate authority and be able to sign certificate requests (CSR) using a minimum of applications. Fortunately, openssl was extremely versatile, if poorly documented.
In order to preform all the CA related functions I started out with a set of Makefiles. These files would do almost everything, but were getting difficult to maintain as I added more features. Eventually I created a script to do the work. The script is a simple shell script and should run anywhere. This script can be found here.
Setup
- Download the script from my github.
- Copy to any directory in the path.
That's it! The script is self contained. By default it will create a $HOME/.pca directory. This can be overridden by specifying PCA_ROOT=/some/path in your environment.
NOTE: A quick note about security. This program predates the availability and use of hardware security modules. It assumes that the filesystem that the CA files are stored in is secure. Maybe a future improvement will be to add the ability to use hardware security module capabilities.
Initialize CA
To start, initialize the CA. This will setup structures and configs openssl will need to become a CA.
pca CANAME initThe setup will only need to be done once per CA. If you would like to have a second CA... just change CANAME to anything else... maybe 2ndCA... and you have a second CA.
To view all the commands and options, just run the pca command.
$ pca
pca 1.6 - Personal Certificate Authroity
pca <ca> <command> [options]
Commands:
<ca> init
<ca> config list <mac[ros] | pol[icy] | ext[ension] | prog[ram]>
<ca> config get macro <-key key> <-value>
<ca> config set macro [-a|-d] <-key key> <-value val>
<ca> config get pol|ext|prog <-name name> <-key key> <-value>
<ca> config set pol|ext|prog [-a|-d] <-name name> <-key key> <-value val>
<ca> config sign <-name name>
<ca> create root [-days #] [-bits #] [-cn name] [-ct x] [-sp x] [-co x] [-or x] [-ou x] [-em x] [ -san val ... ]
<ca> create crl
<ca> create key <-name name> [-bits #]
<ca> create chain
<ca> create req[uest] <-name name> <-key file | -newkey [#bits]> [-days #] [-cn name] [-co x] [-sp x] [-ct x] [-or x] [-ou x] [-em x] [ -san val ... ]
<ca> show crl [-issuer] [-hash] [-fingerprint] [-num] [-last] [-next]
<ca> show req [-name name]
<ca> show root [-serial] [-expire] [-subject] [-subjecthash] [-issuer] [-issuerhash] [-fingerprint]
<ca> show cert [-name name] [-serial] [-expire] [-subject] [-subjecthash] [-issuer] [-issuerhash] [-fingerprint] [-client] [-ca]
<ca> sign <-name name> [-sign] [-days] [-san val ...] [-ext alt_extension]
<ca> resign <-name name> [-sign] [-days]
<ca> revoke <-name name | -serial #> [-crl]
<ca> delete req|key|cert <-name name>
<ca> export pkcs12 <-name name> <-file name> <-pass -|file:filename|password> [-chain] [-overwrite]
<ca> export html <-file name> [-overwrite]
<ca> export cert <-name name> <-file name> [-overwrite] [-chain]
<ca> import pkcs12 <-name name> <-file name> <-pass -|file:filename|password> [-overwrite]
<ca> import request <-name name> <-file name> [-overwrite]
Basics Uses
Below are the basics of creating and maintaining a CA.
Create a CSR
To create a CSR and associated key, run the create req command.
pca CANAME create req -name CERT1 -newkey -cn CERT1 -san DNS=CERT1This will create a CSR and KEY setting the subject to CN=CERT1 and the Subject Alternative Name (SAN) to CERT1.
Show unsigned CSRs
To show all unsigned CSRs run the show req command.
pca CANAME show reqSign a CSR
To sign a CSR run the sign command.
pca CANAME sign -name CERT1This will sign the CSR and create the certificate.
Show signed Certificates
To show signed certificates run the show cert command. It's important to note that unless a certificate is deleted, it will continue to show in this list regardless of its state (valid, expired or revoked)
pca CANAME show certRevoke a certificate
If a certificate needs to be revoked because it expired or for any other reason, use the revoke command.
pca CANAME revoke -name CERT1Resign a certificate
It may not be desirable to just revoke a certificate and create a new request and then sign that request. That is a lot of steps! Fortunately for everyone I got tired of that dance and created a resign command to resign an existing certificate and give it a new expiration date.
pca CANAME resign -name CERT1Import a CSR
There may come times when a CSR is created outside of the PCA program. In those cases, the CSR can be imported and then signed. Use the import request command.
pca CANAME import request -name EXTCERT2 -file EXTCERT2.csrNow the certificate can be signed, resigned, revoked, etc like any other certificate/request.
Export certificate and key
Now that we can create a certificate (and key) we need a way to export them from the CA so they can be used on a device, server, etc. To do this the standard was of exporting a certificates and keys securely is to use a PKCS12 file. To do this use the export pkcs12 command.
pca CANAME export pkcs12 -name CERT1 -file CERT1.p12 -pass a_better_password_should_be_choosen -chainThis will create a CERT1.p12 file with the certificate, key and certificate chain. These can be transferred to any system and exported using the openssl pkcs12 commands.
Export the certificate
openssl pkcs12 -in CERT1.p12 -nokeys -clcert -out CERT1.crtExport the key
openssl pkcs12 -in CERT1.p12 -nocerts -nodes -out CERT1.keyExport the chain
openssl pkcs12 -in CERT1.p12 -nokeys -cacert -out CANAME_chain.pemDepending on what system the PKCS12 files was created and what system the cert/key/chain is being extracted to the -legacy flag may need to be specified.
Export Certificate (only)
In cases where the CSR was imported or where only the certificate needs to be exported, the PKCS12 format may not be necessary. To export only the certificate use the export cert command.
pca CANAME export cert -name EXTCERT2 -file EXTCERT2.crtAdvanced Uses
Openssl uses various files and configurations to run the CA. The init command above created the defaults of these files. But for reasons of your own, you may need to update/change these default files. There are 4 types of files that get used: Macros, Policy, Extension, and Program files. To view the defaults for these files run the config list <type> command.
pca CANAME config list progThe files that you will probable change the most often are the policy and extension files as these control how openssl behaves based on different types of inputs.
To make a change to one of the files use the config set command.
pca CANAME config set pol -name POLICY_NAME -key KEY_NAME -value VALUEIf a key needs to be added or deleted use the -a or -d flags when calling the set command.
Conclusion
Hopefully this article helps you consider running your own certificate authority and shows you how easy it can be.
Feel free to provide me any comments, questions, or feedback.