Creating and running your own certificate authority (CA) is how you can issue your own SSL certificates. This is not for everyone but can save a lot of hassle and money in the right circumstances. Herein I’ve documented the steps I successfully took to get set up with a CA on Ubuntu Linux using OpenSSL.
[UPDATED Friday, April 9, 2015 (2015/04/09)]
Much of this requires superuser permissions. I find it easier to just temporarily sign in as root rather than prefacing everything with “sudo”, but don’t forget to “exit” afterwards.
First set up a place to keep your public key infrastructure (PKI).
All PKI begins with a private key. Create a new private key for yourself as a certificate authority (CA).
openssl genrsa -out ca_root.key 8192
= Use the openssl software to generate a new, private, RSA cryptographic key, 8192 bits in length, saved as “ca_root.key”.
The private key can optionally be encrypted and secured with a passphrase by adding an (singular / just one) encryption option to the private key creation command [genrsa].
If you do not know which you want to use, then I recommend AES256. 
You then need to create a certificate signing request (CSR). A CSR provides identifying information (e.g. your name) and is signed by a private key.
openssl req -verbose -new -sha256 -extensions v3_ca -days 3650 -key ca_root.key -out ca_root.csr -utf8
= Use the openssl software to generate a CSR using the SHA256 algorithm and version 3 extensions for a CA, good for 10 years after creation (365 days per year * 10 years), signed with the private key “ca_root.key”, and saved as “ca_root.csr” in UTF-8.
- If the PK is getting encrypted by default and you do not want that, then use the option “-nodes” (as in [no DES]).
This CSR then needs to be self-signed with the private key to be a root CA X.509 certificate. By self-signing, the CA is certifying that it is itself. The signed certificate is the public key portion of PKI. Self-sign the CSR.
openssl x509 -req -in ca_root.csr -signkey ca_root.key -days 3650 -out ca_root.pem
= Use the openssl software to generate an X.509 certificate from the CSR “ca_root.csr”, self-signed by the private key “ca_root.key”, good for 10 years after creation (365 days per year * 10 years), and saved as “ca_root.pem”.
You can check out / read / look at your key, request, and certificate, if you are interested:
openssl rsa -in ca_root.key -noout -text
openssl req -in ca_root.csr -noout -text
openssl x509 -in ca_root.pem -noout -text
= Simply calling cat (“concatenate”) will show you the encrypted contents. Calling openssl with rsa or x509, respectively, will decrypt the key and certificate showing you their human-readable contents.
- To the best of my searching, the CA root certificate serial number is irrelevant.
Copy the public certificate and change the extension from .pem to .crt for use/installation on Microsoft Windows.
cp ca_root.pem ca_root.crt
The root CA certificate needs to be added to the certificate management store wherever it needs to be trusted. e.g. Internet Explorer (Chrome uses the same store) and Firefox.
– Internet Explorer > Menu or Tools > Internet Options > Content tab > Certificates > Trusted Root Certification Authorities tab > Import
- The default “Certificate intended purposes” should be sufficient, but if they might not be then you can change them by selecting the certificate and clicking the “Advanced” button.
– Firefox > Menu or Tools > Options > Advanced section > Certificates tab > View Certificates > Authorities tab > Import > choose what the certificate is supposed to identify (e.g your website, your email address).
 ,  , 
Using the CA to sign CSRs will require a flat-file text database, a serial number file, and a configuration file. Store these in the configuration directory.
echo "01" > conf/ca_root.srl
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
dir = /etc/keys/ca # top dir
database = $dir/conf/index.txt # index file.
new_certs_dir = $dir/certs # new certs dir
certificate = $dir/ca_root.pem # The CA cert
serial = $dir/conf/ca_root.srl # serial no file
private_key = $dir/ca_root.key # CA private key
default_days = 730 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha256 # md to use
policy = policy_any # default policy
email_in_dn = no # Don't add the email into cert distinguished name (DN)
name_opt = ca_default # Subject name display option
cert_opt = ca_default # Certificate display option
copy_extensions = copy # Don't copy extensions from request
[ policy_any ]
countryName = supplied
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
- The serial number in ca_root.srl will be automatically incremented by OpenSSL each time the CA is used to sign new certificates.
Each end entity certificate you wish to create and sign (e.g. for your website, email) will need its own private key. Create a new private key.
openssl genrsa -out certs/entity.key 4096
- The bit length used here (4096) is smaller than that used for the original CA root key, but it doesn’t have to be.
Create a CSR for the end entity using the new private key.
openssl req -verbose -new -sha256 -days 1825 -key certs/entity.key -out certs/entity.csr -utf8
- We are no longer using “-extensions v3_ca” because we aren’t signing a CA root certificate.
- A wildcard certificate can be created by putting *.domain.tld as the common name (using your domain and tld; also potentially a subdomain as wildcards can only cover a single level of subdomain matching; a wildcard name will *NOT* match the naked domain [*.domain.tld will not work with domain.tld]).
- Additional names can be included/supported using an openssl configuration file and the subjectAltName extension.
Sign the CSR using the CA.
openssl ca -verbose -config conf/openssl.ca.conf -in certs/entity.csr -out certs/entity.crt -days 1825 -utf8
= Use the openssl software to sign the CSR “entity.csr” with the CA and options specified in the configuration file “openssl.ca.conf”, saving the resulting certificate as “entity.crt”.
- The CA cannot sign a certificate with the same common name as an active (un-revoked) certificate.
Creating a wildcard certificate with the naked domain name included as a SubjectAltName requires the use of a configuration file.
[ req ]
default_bits = 4096
default_keyfile = entity.key
encrypt_key = no
default_md = sha256
prompt = no
utf8 = yes
distinguished_name = my_req_distinguished_name
req_extensions = my_extensions
[ my_req_distinguished_name ]
C = US
ST = Michigan
L = .
O = LogSine
CN = *.logsine.com
[ my_extensions ]
basicConstraints = CA:false
subjectAltName = @my_subject_alt_names
subjectKeyIdentifier = hash
[ my_subject_alt_names ]
DNS.1 = *.logsine.com
DNS.2 = logsine.com
- You create a CSR using this config using:
openssl req -verbose -new -sha256 -days 1825 -key certs/entity.key -out certs/entity.csr -config certs/entity.conf
If you accidentally sign a certificate, for a given/particular common name, that isn’t set up how you want it, then you will have to revoke the incorrect/old certificate before OpenSSL will let you sign a new one for the same common name. Revoking a certificate issued by your CA is very easy – just use the same CA configuration file and the -revoke option:
openssl ca -verbose -config conf/openssl.ca.conf -revoke certs/entity.crt
- Getting anything else to recognize revoked certificates involves certificate revocation lists (CSLs).
Are you willing to try a third-party tool if it might be easier?
- Certificate Management Tool by Real Time Logic
- “TinyCert: Generate SSL Certificates And Become Your Own Certificate Authority” by Tyler Longren ( , , ) about using TinyCert
● The bit-length of a private key defines how many possible combinations it could be, and thus determines the difficulty of “breaking” its security by trying to guess it. However, making it longer also increases the amount of processing time it takes to create, transfer, etc. Also, many applications may have limits on the length of SSL certificate accepted. For the tutorial below, I simply picked a longer bit-length than was recommended at the time I was learning about it but was also what I guessed was not too large to be accepted by modern applications.
- “Recommendation for Key Management – Part 1: General (Revision 3)” by Elaine Barker, William Barker, William Burr, William Polk, and Miles Smid of the United States National Institute of Standards and Technology (NIST) – Information Technology Laboratory – Computer Security Division, 2012/06
see “Table 4: Security-strength time frames” on page 67
- “Anatomy of a change – Google announces it will double its SSL key sizes” by Paul Ducklin on Naked Security on Sophos, 2013/05/27
- “Key size” on Wikipedia, accessed 2015/04/09
● Although creating your own certificate authority is currently the only way to freely obtain a bunch of otherwise obscenely [extortionately?] expensive SSL certificates, Let’s Encrypt (sponsored by the likes of Mozilla and the Electronic Frontier Foundation (EFF)) may be a viable, free option in the future.
● SHA1 began to be phased out in September, 2014. SHA256 (a.k.a. SHA2) is its replacement. Although OpenSSL supports algorithms other than SHA256, I wouldn’t use them.
- “Gradually Sunsetting SHA-1” posted by Chris Palmer and Ryan Sleevi on the Chromium Blog, 2014/09/05
- “Phasing Out Certificates with SHA-1 based Signature Algorithms” posted by Kathleen Wilson on the Mozilla Security Blog, 2014/09/23
- Learn about OpenSSL configuration files.
- Read up on and try using an Intermediate Certificate Authority certificate.
- Learn about the authorityInfoAccess certificate extension and Online Certificate Status Protocol (OCSP).
- : “Recommendations for TLS/SSL Cipher Hardening” by Ian Muscat ( , ), on Acunetix, 2014/10/15
- : “Q12149 – HOWTO: DER vs. CRT vs. CER vs. PEM Certificates and How To Convert Them” on info.SSL.com, 2014/09/03
- : find section “Importing the Trusted Root Certificate” David Pashley ( ), 2014/07/25
- : “Install Root Certificate in Internet Explorer” on PowerAdmin.com, accessed on 2015/03/16
- : “Installing root certificate in Mozilla Firefox” on WebMoney, accessed on 2015/03/16
- Becoming a X.509 Certificate Authority by David Pashley ( ), 2014/07/25
- Self Signed Certificates the right way by Marcus Povey ( , , , ), 2014/07/09
- How to setup your own CA with OpenSSL gist by Igor Soarez ( ) on GitHub, 2014/03/21
- How to Be Your Own Certificate Authority on wikiHow, 2015/02/08
- OpenSSL Essentials: Working with SSL Certificates, Private Keys and CSRs by Mitchell Anicas on Digital Ocean, 2014/09/12
- Home » OpenSSL » Revoke Certificate on Antoine Solutions Development, accessed on 2015/04/01
- Certificate authority on Wikipedia
- Self-signed certificate on Wikipedia
- Wildcard certificate on Wikipedia
Services, Tools, and Resources
- A Web PKI x509 certificate primer, on MDN
- Introduction to Public-Key Cryptography, on MDN
- OpenSSL genrsa, in OpenSSL documentation
- OpenSSL rsa, in OpenSSL documentation
- OpenSSL req, in OpenSSL documentation
- OpenSSL x509, in OpenSSL documentation
- OpenSSL ca, in OpenSSL documentation
- How to create my own certificate chain? on superuser
- why can’t i generate a new certificate with openssl? on LinuxQuestions
- When does Firefox throw ssl_error_bad_cert_domain with a wildcard certificate? on stackoverflow
- What counts as a self-signed SSL certificate? on stackoverflow