Note, update: This has a follow up post for the case where you want to keep any Subject Alternativ Name (SAN) fields in the certificate to sign.
On occasion, I’ve needed to create my own self-signed SSL-certificates for various testing purposes. At work today I needed a certificate that was signed by another certificate, i.e. I needed a chain of trusted certificates for testing, where the cert at the top of the chain is used as a trusted root certificate. The premise is is simple: If you trust the root certificate, you should also trust the certificates further down in the chain, since they are signed using the trusted certificate.
I generally work on a Windows system, but for certain tasks such as this, I often find Unix-style tools preferable. Luckily, if you used the Git Bash command line for windows and have OpenSSL included, you’ll have everything you need right there. This post provides a few quick steps needed to create such a chain of trusted certificates using OpenSSL.
Step 1: Define a Certificate Authority (CA)
Create a plain text file with the following content, and save it as e.g. CertAuth.conf:
[ ca ] default_ca = ca_default [ ca_default ] dir = ./certauth certs = $dir new_certs_dir = $dir/certs database = $dir/db serial = $dir/serial RANDFILE = $dir/rand certificate = $dir/ca.crt private_key = $dir/ca.key default_days = 365 default_crl_days = 30 default_md = md5 preserve = no policy = generic_policy [ generic_policy ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = optional emailAddress = optional
Step 2: Add required files to the certauth directory
Create a directory certauth (corresponding to
$dir in the script above). This is where files needed by the CA will be placed.
certauth, create a directory
certs, an index-file
index, and a database file,
cd certauth mkdir certs touch index touch db
Step 3: Create a private key and a certificate for the CA
Create a 1024-bit RSA key for the certificate authority you just defined (from the bash command line while in the
ca directory). This will ask you to choose (and confirm) a password for the key.
openssl genrsa -des3 -out ca.key 2048
…and then use that key to sign a certificate. You’ll need to provide the password the password you chose previously now, in order to use the key you just created, and enter some data about the certificate (country, region, organization name, etc. – you can leave some of these blank if you like).
openssl req -new -x509 -days 10000 -key ca.key -out ca.crt
Step 4: Create a Certificate Signing Request
Now that the CA and root cert is ready, we can create a request for a certificate is signed by the root cert created above. First, create a file similar to the following example, and save it as signreq.req in the outer directory (not under
certauth). NOTE: Be sure to save this in ANSI, to avoid any encoding errors:
[req] default_bits = 2048 prompt = no default_md = sha256 x509_extensions = v3_req distinguished_name = dn [dn] C = NO O = Acme Security Industries Ltd CN = My Dummy Cert [v3_req]
…then generate the request based on that file; this will generate the request as
myreq.pem, and a corresponding private key as
openssl req -new -newkey rsa:2048 -nodes -keyout mykey.key -out myreq.pem -config signreq.req
Step 5: Generate the signed cert based on the request, using the CA
Finally, let’s generate the signed certificate based on the recently created request, using the previously created CA. This includes
-create_serial in order to generate a random number / id for the cert, which is stored in the CA along with other basic info about the cert.
You’ll be asked for the password again here, and then requested to confirm the signing of the certificate for the given period, and then to commit the signing.
openssl ca -config certauth.conf -create_serial -out certificate.crt -infiles myreq.pem
That should provide you with a signed certificate called
certificate.crt. If you open it however, you’ll see the following status, and see a warning icon over the cert. Why is this? Simple: You haven’t imported the root certificate yet.
Post-step: Import the dummy root cert
Go into the
certauth folder and locate the cert you intend to use as a root cert;
ca.crt. If you open it, you’ll see that it is untrusted:
Click Install Certificate to install it, and select Trusted Root Certificates as the place to store it. Be careful doing this of course – you don’t want to accidentally trust ant certificates that are not really trustworthy. In fact, I’d recommend removing the certificate from here once you’re done testing, even if only to keep things clean and tidy.
Now that you have chosen to trust the root certificate, you can once again open both certificates and have a look: The root cert should be trusted directly, and the other one (which was signed using the root cert) should be trusted indirectly via its certification path / trust chain: