Generating Self-Signed X.509 Certificates

People who know me know that I love to dis on X.509 based security solutions. Whether it's implementations that just plain ignore basic constraints, or popular certification authorities that add an extra zero byte to the end of their certs... it's all just so much fun.

But it's hard to argue with the utility of a properly configured TLS layer. And until we add a TLS extension for using OpenPGP to cart around public keys in TLS handshake sequences, we're sort of stuck with X.509.

I spend a surprising amount of time generating self-signed certificates for testing, so a few decades ago I came up with a bash script to eliminate the drudgery of this process. If you're interested, just grab a copy from GitHub at:

To use it, just copy and paste it from the gist page into a file you've chmod +x'd. To use it, just run the script passing the name of the host you're generating a certificate for as the first parameter. It defaults to making 2048 bit keys with no passwords, so don't use this to generate production certs (not that you should be using self-signed certificates in a production environment anyway.)

So if I wanted to create a certificate for, and I named the script gssc, i would invoke it like so:


and it would generate two files: and The former contains the private key and the latter is the X.509 certificate for

The -b, -p and -s options allow you to change the length of the private key, the password to encrypt the private key and the certificate's subject name. So if I wanted to create a 1024 bit private key, encrypted with the password "blargh" and with the subject name "C=IO, ST=Chacos, L=Diego Garcia,," I would use this command:

   gssc -b 1024 -p blargh \
     -s "/C=IO/ST=Chacos/L=Diego Garcia/"

And for completeness sake, here is a copy of the script if you don't want to (or can't) grab it from the GIST referenced above:

   # Copyright (c) 2003-2013, Meadhbh S. Hamrick. All Rights Reserved.
   # Released under a BSD License. See
   # This script uses openssl to generate a self-signed certificate. Usage is
   # like this:
   #   gssc  [-p password] [-s subject] [-b bitlength]
   # The host name parameter is the subject name of the certificate; i.e. - the
   # FQDN of the host you're generating a certificate for. This is also the base
   # name for the key, certificate signing request and certificate files. If you
   # want the key to be protected by a password, use the -p option to specify
   # it. The subject name of the requested cert defaults to:
   #   "C=US, ST=California, L=Felton, CN="
   # You can select a differetn subject name by using the -s option and providing
   # a complete openssl style subject name. For example:
   #   "/C=IO/ST=Chagos/L=Diego Garcia/"
   # will specify the expected subject name. Remember to put the slashes
   # in front of each clause and to put the Common Name (CN) entry (we don't
   # do it for you.) By default, we generate 2048 bit RSA keys. If you want some
   # other bit length, use the -b flag.
   # For example, the following command generates a self signed cert for the
   # machine "" with a 1536 bit RSA key and a common name of
   # "C=US, ST=Montana, L=Bozeman,":
   #   gssc -b 1536 -password "badpassword" \
   #       -s "/C=US/ST=Montana/L=Bozeman/"
   # This example creates a self signed cert for with no password
   # on the private key and a subject name of "C=US, ST=California, L=Felton,
   #   fssc
   # Cheers!
   # Check to see if we provided a host name
   if [ $# -lt 1 ]; then
     echo "Usage: $0  [-b bits] [-p password] [-s subject name]"
     exit 1
   # Set up defaults
   # Now apply the parameters
   while getopts "b:p:s:" flag
     case $flag in
       b) BITS=$OPTARG;;
       p) PASSWORD=$OPTARG;;
       s) SN=$OPTARG;;
   # First off, generate a RSA key
   if [ 0 = ${#PASSWORD} ]; then
     openssl genrsa -out $CN.key $BITS
     if [ 4 -gt ${#PASSWORD} ]; then
       echo "Your pass phrase must be four or more characters."
       exit 2
       openssl genrsa -out $CN.key -des3 -passout "pass:$PASSWORD" $BITS
   # Now create the certificate
   if [ 0 = ${#PASSWORD} ]; then
     openssl req -new -batch -x509 -key $CN.key -subj "$SN" -days 365 -out $CN.crt
     openssl req -new -batch -x509 -key $CN.key -subj "$SN" -days 365 -out $CN.crt \
       -passin "pass:$PASSWORD"