There are many ways to get an SSL certificate; either paid or free, for your local development server. Depending on the operating system you use, this process can be quite simple or complex, involving installation of multiple supporting packages.
In this post, I'm going to delve into the simplest way to get a free SSL certificate using Windows. And I'm not talking about a self-signed certificate that doesn't validate in a browser. This is the real deal.
You have probably already heard of Let's Encrypt (often shortened to LE)
Let's Encrypt is a non-profit certificate authority run by Internet Security Research Group (ISRG) that provides X.509 certificates for Transport Layer Security (TLS) encryption at no charge. It is the world's largest certificate authority, used by more than 265 million websites, with the goal of all websites being secure and using HTTPS.
Since the information on their website is fairly technical, I'm going to break it down into a few simple steps, so that beginners can get an SSL certificate and install it on their local server. For this example, I'm going to use a simple WAMP stack, called XAMPP.
Step 1: Get the tool
Head over to Alexander Yezhov's Github repository for Crypt-LE and download le32.zip or le64.zip depending on whether you're using 32-bit or 64-bit Windows.
Alexander Yezhov created ZeroSSL - which used to be a free tool to generate Let's Encrypt SSL certificates online. It has changed hands and is now a commercial project.
Step 2: Unzip the tool
Unzip the file you just downloaded, to a folder on your computer. To make it easier to reference this folder in the rest of this post, I'll assume you unzipped to C:\le64\
Step 3: Run some commands
Fire up the terminal. Click Start, type cmd, select Command Prompt and press enter.
Now, you're ready to type in the following commands.
Navigate to the directory with le64.
cd \le64
Next, run the le64.exe command with the delayed switch, so you have enough time to setup the required domain validation.
le64.exe -domains "dev.hostname.com, www.dev.hostname.com" -handle-as http -delayed -live -generate-missing -key account.key -email "youremail@hostname.com" -csr dev.hostname.com.csr -csr-key dev.hostname.com.key -crt dev.hostname.com.crt
Explanation of each switch
le64.exe | The executable that does all the work |
-domains "dev.hostname.com, www.dev.hostname.com" | List of all your hostnames/domains; comma separated, in double quotes. These should be publicly accessible domains, because LE needs to validate them. So, you can't use names like localhost. If you have a dynamic IP, use a DDNS service. |
-handle-as http | LE has two main methods of validation - HTTP or DNS. To keep it simple, for your local server, let's use HTTP. This includes creating a file with specific content that will be provided to you by LE. |
-delayed | The delayed switch requests a validation challenge and then exits. After setting up the validation challenge, you can run the same command later, without the delayed switch, to continue. |
-live | Use the live server instead of the test server to generate a certificate. |
-generate-missing | Generate missing key, csr and csr-key files. |
-key account.key | Path to the account key file |
-email "youremail@hostname.com" | Your working email address. Certificate expiration notifications are sent here. |
-csr dev.hostname.com.csr | Path to the CSR file. If it doesn't exist, it will be generated. |
-csr-key dev.hostname.com.key | Path to the private key file. If it doesn't exist, it will be generated. |
-crt dev.hostname.com.crt | Name for the domain certificate file. LE will store the generated certificate here, along with the CA bundle. |
After executing the command, your output should be similar to this
[ ZeroSSL Crypt::LE client v0.35 started. ]
Generating a new account key
Saving generated account key into account.key
Generating a new CSR for domains dev.hostname.com, www.dev.hostname.com
New CSR will be based on a generated key
Saving a new CSR into dev.hostname.com.csr
Saving a new CSR key into dev.hostname.com.key
Registering the account key
The key has been successfully registered. ID: 1234
Make sure to check TOS at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Current contact details: youremail@hostname.com
Challenge for dev.hostname.com requires:
A file 'abc123' in '/.well-known/acme-challenge/' with the text: abc123def
Step 4: Setup the domain challenge for validation
Create the required folders in your web root and then create the requested file (eg. abc123). Add the requested text (eg. abc123def) to the file. This is fairly simple and can be done in Notepad or a code editor like Visual Studio Code.
Open your web browser and make sure this file is visible. Eg. http://dev.hostname.com/.well-known/acme-challenge/abc123
Step 5: Validate domain and get the certificate
Now, it's time to run the previous command again, but without the delayed switch.
le64.exe -domains "dev.hostname.com, www.dev.hostname.com" -handle-as http -live -generate-missing -key account.key -email " youremail@hostname.com" -csr dev.hostname.com.csr -csr-key dev.hostname.com.key -crt dev.hostname.com.crt
The output will be similar to this
[ ZeroSSL Crypt::LE client v0.35 started. ]
Loading an account key from account.key
Loading a CSR from dev.hostname.com.csr
Registering the account key
The key is already registered. ID: 1234
Current contact details: youremail@hostname.com
Challenge for dev.hostname.com requires:
A file 'abc123' in '/.well-known/acme-challenge/' with the text: abc123def
When done, press <Enter>
Domain verification results for 'dev.hostname.com, www.dev.hostname.com': success.
You can now delete the 'abc123' file.
Requesting domain certificate.
Requesting issuer's certificate.
Saving the full certificate chain to dev.hostname.com.crt.
The job is done, enjoy your certificate!
You'll have four new files in the le64 folder.
Step 6: Setup the SSL certificate in xampp
We now have all we need to setup the certificate in XAMPP. Browse to the apache\conf folder in your xampp installation folder: For eg: D:\xampp\apache\conf
Move the key file dev.hostname.com.key from le64 to the apache\conf\ssl.key\ folder.
Move the certificate file dev.hostname.com.crt from le64 to the apache\conf\ssl.crt\ folder.
Now, open the file \apache\conf\extra\httpd-vhosts.conf
You should already have the following text block in place for the hostname without SSL
<VirtualHost *:80>
ServerAdmin postmaster@localhost
DocumentRoot "D:/webroot"
ServerName dev.hostname.com
ServerAlias www.dev.hostname.com
ErrorLog "logs/localhost-error.log"
CustomLog "logs/localhost-access.log" combined
</VirtualHost>
Add this block of text to access the hostname with SSL
<VirtualHost *:443>
ServerAdmin postmaster@localhost
DocumentRoot "D:/webroot"
ServerName dev.hostname.com
ServerAlias www.dev.hostname.com
ErrorLog "logs/localhost-error.log"
CustomLog "logs/localhost-access.log" combined
SSLEngine on
SSLCertificateFile "conf/ssl.crt/dev.hostname.com.crt"
SSLCertificateKeyFile "conf/ssl.key/dev.hostname.com.key"
</VirtualHost>
If you're using an older version of Apache, prior to 2.4.8, then you will need to split the certificate into a CA bundle file and add an extra line in httpd-vhosts.conf to reference it.
SSLCertificateFile "conf/ssl.crt/dev.hostname.com.crt"
SSLCertificateChainFile "conf/ssl.crt/dev.hostname.com_cabundle.crt"
SSLCertificateKeyFile "conf/ssl.key/dev.hostname.com.key"
To split the certificate file into the certificate and CA bundle, open the dev.hostname.com.crt file in Notepad or similar text editor. It will contain 2 or 3 blocks of text, which look similar to this:
-----BEGIN CERTIFICATE-----
MIIDrDCCApQCCQCqJIUfSVAQHjANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMC
SU4xDDAKBgNVBAgMA0dvYTEPMA0GA1UEBwwGTWFwdXNhMRMwEQYDVQQKDApXYXJy
ZW5hc2lhMQwwCgYDVQQLDANXZWIxIjAgBgNVBAMMGXByb2R1Y3Rpb24ud2FycmVu
YXNpYS5jb20xIjAgBgkqhkiG9w0BCQEWE2luZm9Ad2FycmVuYXNpYS5jb20wHhcN
MTkxMDA5MTgxNjA1WhcNMjAxMDA4MTgxNjA1WjCBlzELMAkGA1UEBhMCSU4xDDAK
-----END CERTIFICATE-----
Leave the first block in the certificate file. Select the text from the second block to the end of the file and paste it in a new file called dev.hostname.com_cabundle.crt
Step 7: Start / restart apache
Now, you can start up your Apache server; or if it's already running, stop and restart it.
Browse to your hostname starting with https://
That's it! You have a valid SSL certificate on your development server. Test in peace.
Questions? Comments? Feel free to post below.