Generating SSL certificates can be a daunting task, one filled with frustration and sorrow. But it doesn't have to be that way! If you are struggling with SSL certificates for your webpages and servers, keep reading.

OpenSSL is a commercial-grade tool developed under an Apache-style license. It is a full-featured cryptography & SSL / TLS toolkit commonly used to create certificate signing requests needed by a certificate authority (CA). OpenSSL can create private keys, sign certificates, generate certificate signing requests (CSR), and much more.

In this article, you're going to learn how to install OpenSSL, generate SSL certificates, troubleshoot and debug certificates, and convert between formats with ease all using PowerShell.

If you're more of a visual learner, feel free to watch this article's companion video below:

Let's begin mastering OpenSSL with PowerShell!

Prerequisites

In this article, you are going to learn using a hands-on approach. While OpenSSL historically is a Linux OS utility, you can use it with Windows OS as well. For the purposes of this article, we are going to use the Windows version. But don't worry, the commands are the same if you choose Linux.

If you choose to follow along, you are going to need a couple of prerequisites:

All screenshots in this guide were taken from Windows 10 build 1909 and PowerShell 7.

Installing OpenSSL using Chocolatey

Assuming you have installed Chocolatey using the installation instructions, your first task is to install OpenSSL. To do this, open up your PowerShell console and run choco install OpenSSL.Lightas shown below.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4327b487-8984-4d3b-a597-9d11cf39080d/buXlnf8cu1.gif
Installing OpenSSL.Light using Chocolatey package manager in PowerShell

That's it! You've completed the installation of OpenSSL.

Set up a Working Directory

It's important to be organized, especially when learning something new. That's why you will want to create a working directory to store your certificates and OpenSSL configuration.

Using the New-Item cmdlet, create a directory as shown below.

New-Item -ItemType Directory -Path C:\certs

Now it's time to configure OpenSSL.

OpenSSL Configuration

By default, OpenSSL does not come with a configuration file. This is intentional because there are a lot of configuration options that you can customize. For the purposes of this guide, you are going to use a sample configuration that you can customize later to best suit your security requirements.

Enter the following code into your PowerShell terminal :

Invoke-WebRequest 'http://web.mit.edu/crypto/openssl.cnf' -OutFile .\openssl.cnf

When you press Enter, do not be alarmed. The download is extremely fast since it's a simple text file of only a couple of KB's. When you look at your working directory, you will see that you now have a a sample configuration file.

Here's what that configuration file looks like in Visual Studio Code:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/cf27548d-91f3-4647-9880-b2958ff55b96/Untitled.png
Sample OpenSSL configuration file in Visual Studio Code

The downloaded configuration will work as-is for now. Do not use the defaults in a production environment!

Update PowerShell Profile Environment Variables

To make things go smoothly, you should modify your PowerShell profile to help you more easily work with OpenSSL in PowerShell. Setting up some environment variables allows you to easily switch between different versions of OpenSSL that you may have installed.

I suggest adding two environment variables to your PowerShell profile called path and OPENSSL_CONF. You will update the PATH environment variable to ensure you can run the openssl binary wherever you need without specifying the entire path and create OPENSSL_CONF for a "shortcut" to the OpenSSL configuration file.

Below you'll see a way to create a profile if you don't already have one, append the OpenSSL binary path to your PATH and assign the configuration file path to OPENSSL_CONF.

# Add environment variables to PowerShell profile

# Test for a profile, if not found create one!
if (-not (Test-Path $profile) ) {
    New-Item -Path $profile -ItemType File -Force
}

# Edit profile to add these lines
'$env:path = "$env:path;C:\Program Files\OpenSSL\bin"' | Out-File $profile -Append
'$env:OPENSSL_CONF = "C:\certs\openssl.cnf"' | Out-File $profile -Append

To use the environment variables, reload your profile typing . $profile or just close and reopen PowerShell.

Now you can easily invoke the openssl binary wherever you are in PowerShell as shown below.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6af3fac7-d082-4a30-954f-457178cb4480/gHRDECraUk.gif
Verifying OpenSSL version in PowerShell

Generating a CSR & Private Key

Before you can create an SSL certificate, you must generate a CSR. A CSR is an encoded file which provides you with a way to share your public key with a CA. This file contains identifying information, a signature algorithm and a digital signature. Let's create your first CSR and private key.

Enter the following code into your PowerShell console. OpenSSL will then prompt you to enter some identifying information as you can see in the following demonstration.

openssl req -new -out MyFirst.csr
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1a35d399-13e4-4a02-9dea-e50f788a3e01/SprQryi8MY.gif
Generating a CSR and Private Key using OpenSSL in PowerShell

Once complete, you will have a valid CSR and private key which can be used to issue an SSL certificate to you. The configuration file defaults can be edited further to streamline this process should you not want to enter data every time you generate a CSR. You can read more about the available options and view sample configurations in the man pages. OpenSSL also has an active GitHub repository with examples too.

Generating RSA Key Pairs

You can create RSA key pairs (public/private) from PowerShell as well with OpenSSL. To do so, first create a private key using the genrsa sub-command as shown below.

# generate a private key using maximum key size of 2048
# key sizes can be 512, 758, 1024, 1536 or 2048. 
openssl genrsa -out rsa.private 2048

When you run this code in your PowerShell terminal, the openssl application will generate a RSA private key with a key length of 2048 bits. This key is generated almost immediately on modern hardware. The resulting key is output in the working directory

Next, generate a public key using the private key that you just created using the rsa sub-command. The syntax below will create a public key called rsa.public in the working directory from the rsa.private private key.

# generate a public key using the private key
openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM

Generating a Self-Signed Certificate

On occasion you may need to generate a self-signed certificate. Self-signed certificates are fine to use for lab use but not a secure practice to use in a production environment. Lets go ahead and create a sample self-signed certificate before moving onto the next task. Enter the command below to create an x509 SSL certificate using SHA256 cryptography that will be valid for 365 days using an RSA key length of 2048 bits. The certificate will be saved to the working directory.

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt

You are now ready to import the certificate into a browser or server. But what do you do when you need to validate certificate information or keys? Keep reading!

Checking CSRs, Certificates, and Keys

Checking the information in a CSR, private key, certificate, or PKCS#12 can save you time troubleshooting SSL errors. Sometimes a wrong key may have been used to create a certificate, for example. You may have the wrong identifying information in the certificate.

Let's start by checking a CSR using the req command and some parameters:

openssl req -text -noout -verify -in .\MyFirst.csr
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4494f63d-0f4a-4aaa-9a62-1a98baf1f110/oFLHlmo9L4.gif
Checking a CSR with OpenSSL in PowerShell

If you recall the details such as country name, organizational name, email address you entered when creating the CSR at the beginning of this guide, should match precisely.

You can also check a certificate using the x509 sub-command with a couple of parameters:

openssl x509 -in .\certificate.crt -text -noout | more
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a0fe363e-7fba-4def-93fc-47bae27c1618/BwsK7qH502.gif
Checking a certificate with OpenSSL with the x509 command in PowerShell

Converting PEM/DER/PKCS#12

There are occasions where an application does not use a particular certificate format. You can run into this issue with an application called HAproxy, for example that requires a PEM certificate when you may have a DER-formatted certificate (.crt .cer .der).

To demonstrate converting a certificate, let's convert the self-signed certificate created earlier in a DER format (certificate.crt) to PEM. Use the code in the following code snippet to do so. This snippet uses the x509 sub-command with the parameter of -inform which should match the format of the -in file followed by the -out format.

openssl x509 -inform der -in .\certificate.crt -out .\certificate.pem

You can also reverse the order if you'd like to the DER format from PEM too as shown below.

openssl x509 -outform der -in .\certificate.pem -out .\certificate.der

And last but not least, you can convert PKCS#12 to PEM and PEM to PKCS#12. This is a file type that contain private keys and certificates. To convert to PEM format, use the pkcs12 sub-command.

openssl pkcs12 -in .\SomeKeyStore.pfx -out .\SomeKeyStore.pem -nodes

You can convert a PEM certificate and private key to PKCS#12 format as well using -export with a few additional options. Below you are exporting a PKCS#12 formatted certificate using your private key by using SomeCertificate.crt as the input source. Using the -certfile option value MyCACert.crt allows you to validate SomeCertificate.crt.

openssl pkcs12 -export -out SomeCertificate.pfx -inkey SomePrivateKey.key -in SomeCertificate.crt -certfile MyCACert.crt

Troubleshooting & Debugging

Now that you can create & convert CSR's, certificates, and key pairs, it's time to learn how to troubleshoot and debug them. OpenSSL comes with commands that make it a breeze to troubleshoot problems.

OpenSSL also allows you to check certificates for file integrity and test for possible data corruption. Using an MD5 checksum, you can use the following code examples to test certificates, keys and CSR's:

# Certificates
openssl x509 -noout -modulus -in .\certificate.crt | openssl md5

# Public / Private Keys
openssl rsa -noout -modulus -in .\privateKey.key | openssl md5

# Certificate Server Request
openssl req -noout -modulus -in .\MyFirst.csr | openssl md5

# Check an external SSL connection
openssl s_client -connect www.google.com:443

You can take the resulting hash to verify your certificate hasn't been modified or corrupted during transport to another system using the OpenSSL md5 sub-command again or another tool like Microsoft's File Checksum Integrity Verifier if OpenSSL is not available. There are other tools online that can verify MD5 hashes too.

Here's a sample of what that code looks like when run in PowerShell:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7c55cc59-23e3-4274-8652-15fb88487ec1/WindowsTerminal_AWgwDH36rC.png
Sample troubleshooting command output with OpenSSL in PowerShell

Final Thoughts

Since OpenSSL is cross-platform like PowerShell, it allows you to learn one way of generating SSL certificates securely for both Windows and Linux hosts and services. This presents you with huge time savings and will help you learn how to work with SSL certificates on multiple platforms.

In this article You have learned how to install and configure OpenSSL in PowerShell, create a CSR, key pair, and SSL certificate. You have also learned how to convert between different certificate formats and do some basic troubleshooting using built-in sub-commands.

I hope that you have found this guide useful and that you start implementing SSL certificates in your environment soon.

Additional Resources