Create Trusted Self Signed Certificates
By properly creating a self signed certificate, we can get rid of the nagging browser errors for good.
Create the `.certs/` Directory.
To get started we'll need a directory to store all of our certificates and private keys.
I have chosen a ~/.certs/
directory, but it can be whatever and wherever you want.
You can do this from the command line with the following.
bash1# Create the ~/.certs directory.23$ mkdir ~/.certs4
Generate and Trust the Root Private Key, and Certificate.
Trust is Key
The secret to producing trusted self signed certificates, is configuring the operating system to to trust the certificate that signed it. As long as the signing certificate is trusted, any certificates it signs will also be trusted.
Generate the Root Private Key
First we'll need a private key. 2048 bits is perfect. Change the -out
directory as needed.
bash1# Generate a private key.23$ openssl genrsa \4 -out ~/.certs/root.key \5 20486
Generate the Root Certificate
Next, we'll generate a self signed certificate that will serve as our development certificate authority.
Again change the -out
directory as needed.
bash1# Generate a self signed certificate that will serve as the Certificate Authority.23$ openssl req \4 -x509 -new -nodes \5 -key ~/.certs/root.key \6 -sha256 \7 -days 1825 \8 -out ~/.certs/root.pem \9 -subj "/CN=Local CA"10
Configure Mac OS to trust the Certificate
Now that we have our self signed certificate, lets tell Mac OS that it should be trusted.
bash1# Tell Mac OS to add the certificate to it's keychain.23$ sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" ~/.certs/root.pem4
Generate Self Signed Development Certificates
Great! Now, we’re ready to generate the self signed certificates for your development sites.
I like to place everything in a ~/.certs/
directory, however you may prefer to place the certificates with their associated projects. It's up to you.
Generate Private Key for Development Domain
First we'll create a new directory within ~/.certs/
for a hypothetical project called test.local
. And then we create the private key.
You can do this is one step with the following.
bash1# Creates a new directory, and a private key within it.23$ mkdir ~/.certs/test.local \4 && openssl genrsa -out ~/.certs/test.local/test.local.key 20485
Generate a Code Signing Request
You can think of a Code Signing Request as an order form that you send the root certificate. The root certificate recieves the code signing request and fulfills the order.
Note the CN=test.local
part of the following command. CN stands for Common Name and its the url that you use to access your site. If it's localhost, be sure to add the port number.
bash1# Create a Code Signing Request.23$ openssl req -new \4 -key ~/.certs/test.local/test.local.key \5 -out ~/.certs/test.local/test.local.csr \6 -subj "/CN=test.local"7
Generate Extension File
A relatively recent requirement for SSL certificates is that they provide a Subject Alternative Name. Without one, Chrome will load the website, however it will display with the familiar red lock, and give an untrusted site warning.
No worries we can add the Subject Alternative Name to our Code Signing Request with an extension file.
bash1# Create an extension file.23$ echo "\nDNS.1 = test.local" >> ~/.certs/test.local/.extfile4
Generate the self signed certificate
Finally we can generate our trusted self signed certificate by sending our code signing request to the root certificate.
bash1# Generate a trusted self signed certificate by sending a CSR to the trusted certificate.23$ openssl x509 -req \4 -in ~/.certs/test.local/test.local.csr \5 -CA ~/.certs/root.pem \6 -CAkey ~/.certs/root.key \7 -CAcreateserial \8 -out ~/.certs/test.local/test.local.crt \9 -days 365 \10 -sha256 \11 -extfile ~/.certs/test.local.extfile12
Verify the Certificate is Trusted
To prove that the certificate is trusted, here's one last command.
bash1# Verify the certificate is trusted.23$ openssl x509 -noout -text -in ~/.certs/test.local/test.local.crt4
Command Reference
Heres a quick reference on all the commands I provided above.
bash1# Generate a private key.2$ openssl genrsa -out example.org.key 2048*34# Generate an untrusted self signed certificate.5$ openssl req -x509 -new -nodes -key $PATH_TO_PRIVATE_KEY -sha256 -days 1825 -out $PATH_TO_SAVE_CERT -subj "/CN=Local CA"67# Tell Mac OS to trust a certificate to sign certificates.8$ sudo security add-trusted-cert -d -r trustRoot -k "/Library/Keychains/System.keychain" $PATH_TO_CERT910# Generate a Code Signing Request11$ openssl req -new -key $PATH_TO_PRIVATE_KEY -out $PATH_TO_SAVE_CSR -subj "/CN=$SITE_DOMAIN_NAME"1213# Create a Code Signing Request extension to add a Subject Alternative Name.14$ echo "\nDNS.1 = $DOMAIN_NAME" >> $PATH_TO_SAVE_EXT_FILE1516# Generate a Certificate from a Code Signing Request17$ openssl x509 -req -in $PATH_TO_CSR -CA $PATH_TO_ROOT_CERTIFICATE -CAkey $PATH_TO_ROOT_PRIVATE_KEY -CAcreateserial -out $PATH_TO_CREATE_CERTIFICATE -days 365 -sha256 -extfile $PATH_TO_EXTENSION_FILE18