Convert .pfx SSL certificate to .key or .pem format


To totally unlock this section you need to Log-in


Login

In the last years Internet have seen a lot of changes, especially in terms of security standars and requirements for almost every website published on the web. One of this requirements is the SSL/TLS certificate, a special purpose certificate, based on PKI infrastructure standard, that let both website and users to exchange data privately (encrypted) as long as we visit that website and we see the common "green lock" icon (or even a simple gray lock) on common web browsers.

For web developers, system engineers and IT/ICT professional staff out there that usually use and manage SSL certificates regularly (for both tests and production environments), I'm going to show you a simple quick guide on how to manage one of the most troublesome aspect of SSL certificates on several IT/ICT systems (Linux and Windows).

Initially, I'll begin showing you the commands you need to convert your .PFX file (that contains the private key part, that will be conserved into our web server) to a seperate certificate and key file.

We will use OpenSSL software suite to manage this kind of conversion. You can use this approach on both Windows or Linux platforms.

This article could, obviously, come in handy even when you need to import your certificates on devices like routers, access points, loadbalancers etc. where you probably need to import certificates and keyfiles in plain text (unencrypted).

After you installed OpenSSL you can start it from it’s Bin folder (on Windows), while on Linux-based systems just open a Terminal or, if you are on a CLI-only system, just use openssl. On Windows open up a command prompt and change directory (cd command) to the folder that contains your .pfx file. Type the following command to extract the private key:

openssl pkcs12 -in [yourfile.pfx] -nocerts -out [keyfile-encrypted.key]

What this command does is extract the private key from the .pfx file. Once entered you need to type in the password (usually associated to the private key during the generation process used to protect your keypair) of the .pfx file.

If you cannot remember it anymore you can just throw your .pfx file away, cause you won’t be able to import it again, so you will need to re-generate a new keypair (private and public keys).

Now let’s extract the certificate:

openssl pkcs12 -in [yourfile.pfx] -clcerts -nokeys -out [certificate.crt]

Just press Enter and your certificate appears.

Sometimes you need to have an unencrypted .key file to import on some devices: be sure to secure this unprotected file properly. If you store your unencrypted keypair somewhere on an unsafe location anyone can have a go with it and impersonate for instance a website or a person of your company. Protect always your private keys and just throw the unencrypted keyfile away when you’re done with it, saving just the encrypted one.

Type the following command to remove the password of the private key extracted previously:

openssl rsa -in [keyfile-encrypted.key] -out [keyfile-decrypted.key]

Again you need to enter the password, that you created during the generation of the private key. You decrypted your private key. In the folder you have used OpenSSL commands you’ll find the certifcate (.crt) and the two private keys (encrypted and unencrypted, so with and without the password protection).

Some devices or system could use only PEM format of the private key so you could b be forced to convert your private key to PEM format. You can do so with the following command (always using openssl):

openssl rsa -in [keyfile-encrypted.key] -outform PEM -out [keyfile-encrypted-pem.key]

NGINX Web Server

Once you have the private key you will need to concatenate your primary certificate file (your_domain_name.crt) and the intermediate certificate file (Your-CA.crt) into a single .pem file.

To concatenate the files, run the following command:

cat your_domain_name.crt Your-CA.crt >> bundle.crt

Open your Nginx virtual host configuration file for the website you're securing.

Make a copy of the existing non-secure server module and paste it below the original (to take as a backup).

Note: If you need your site to be accessible through both secure (https) and non-secure (http) connections, you'll need a server module for each type of connection, otherwise just remove the server section related to port 80 (http).

Next, add the lines in bold below:

server {

listen   443;
ssl    on;
ssl_certificate    /etc/ssl/your_domain_name.pem; (or bundle.crt)
ssl_certificate_key    /etc/ssl/your_domain_name.key;

server_name your.domain.com;
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
location / {
root   /home/www/public_html/your.domain.com/public/;
index  index.html;
}

}

Adjust the file names to match your certificate files:

The ssl_certificate should be your primary certificate combined with the intermediate certificate that you made in the previous step (e.g., your_domain_name.crt).

The ssl_certificate_key should be the .key file (without password) generated when you created the CSR (generation request of the certificate and keypair from the Certification Authority you have used).

Once done, just run the following command to restart the Nginx service on Linux:

sudo /etc/init.d/nginx restart

At this point you will have installed with success your SSL/TLS certificate.

Lighttpd Web Server

Simalrly for Nginx web server (with an important difference), even Lighttpd needs to concatenate both the domain certificate file .crt file to your private key .key file to works properly for your website.

cat your_domain_name.key your_domain_name.crt > your_domain_name.pem

At this point we will need to edit the Lighttpd configuration file, usually located at /etc/lighttpd/lighttpd.conf, that you can open with command text editors as vi, vim or nano.

Now open your lighttpd.conf file and add the following:

var.confdir = "/etc/lighttpd"
$SERVER["socket"] == "10.10.10.10:443" {
ssl.engine = "enable"
ssl.pemfile = var.confdir + "/your_domain_name.pem"
ssl.ca-file = var.confdir + "/DigiCertCA.crt"
server.name = "your.domain.com"
server.document-root = "/my/document/root/"
}

Make sure that the var.confdir (/etc/lighttpd) matches the location where you saved your certificate files. Also change the external/public IP address (10.10.10.10) to match your IP address (you can also specify the public DNS name here).

Save and close the configuration file. Finally restart Lighttpd service using the following command:

/etc/init.d/lighttpd restart

Apache Web Server

After we have extracted the private key from our .PFX file we are ready to configure our SSL/TLS certificate (with the .crt file for our website, the .crt of our CA and the .key already extracted) within Apache configuration file.

The location and the name of the Apache configuration file could differ and this is based on the server version and OS version (but also if we have installed the httpd or apache2 packages).

As a general rule, the file may be called httpd.conf, apache2.conf or ssl.conf and may be located at /etc/httpd/, /etc/apache2/ or /etc/httpd/conf.d/ssl.conf.

The configuration file contains the Virtual Hosts (VHosts) for all domains that are hosted on the server.

If you have Apache server installed on an Ubuntu system, each website will be specified in separate configuration files that can be found at /etc/apache2/sites-enabled/. To have your site accessible via secure and non-secure connection, you will need two separate configuration files: one for port 80 and the other for port 443.

Often, the SSL certificate configuration is located in a <VirtualHost> block in a different configuration file for the website we want to secure (just to keep separate different configurations, this is not a "must" rule).

Below is a very simple example of a VirtualHost configured for SSL. The parts in bold and italic are what we must add and modify for SSL configuration.

<VirtualHost *:443>
    DocumentRoot /var/www/html2
    ServerName www.yourdomain.com
        SSLEngine on
        SSLCertificateFile /path/to/your_domain_name.crt
        SSLCertificateKeyFile /path/to/your_private.key
        SSLCertificateChainFile /path/to/Your-CA.crt
    </VirtualHost>

Make sure to adjust both the path and filenames to match your certificate files and location on the filesystem.

Now let's see what is what we have added to our VirtualHost configuration file to enable HTTPS communication:

  • SSLCertificateFile is your CA certificate file for your domain (e.g., your_domain_name.crt).
  • SSLCertificateKeyFile is the .key file generated when you created the CSR (e.g., your_private.key).
  • SSLCertificateChainFile is the CA intermediate certificate file (e.g., Your-CA.crt)

NOTE: If the SSLCertificateChainFile directive does not work (the httpd or apache2 service will fail during restart), try using the SSLCACertificateFile directive instead.

Before restarting Apache (httpd or apache2) we could check the Apache configuration file for any syntax errors by issuing the following command to test it (on some systems, it's apache2ctl):

apachectl configtest

If the test will be successfull we will proceed with the service restart. You can use apachectl commands to stop and start Apache with SSL support.

apachectl stop
apachectl start

In case of Apache httpd (on Ubuntu or CentOS systems for example) we could use both service or systemctl commands:

service httpd restart
systemctl restart httpd

In some cases Apache doesn't restart with SSL support: in this scenario you could use apachectl startssl instead of apachectl start command to start properly your website.

If SSL support only loads with apachectl startssl, we recommend you adjust the apache startup configuration to include SSL support in the regular apachectl start command.

Otherwise, your server may require to manually restart Apache using apachectl startssl in the event of a server reboot: this usually will be achieved by removing the <IfDefine SSL> and </IfDefine> tags that enclose your SSL configuration (usually in listen.conf configuration file).

Some notes about SSL/TLS certificates (NGINX - LIGHTTPD - APACHE)

  • Use an uncrypted key file for NGINX and Apache otherwise they'll ask for the password every time these services are restarted.
  • Check the top of the extract .crt file for extra bits above the ----BEING... line and remove if necessary.
  • Test the cert with openssl s_client -showcerts -connect www.domain.com:443.
  • Open a web browser and test/visit your site using https.
  • It is best to test with both Internet Explorer (for legacy purposes) as well as EDGE, Firefox, Chrome and Opera because some modern browsers will give you a warning if your intermediate certificate (CA) is not installed.
  • If you immediately receive a browser message about the site not being available, then the web server may not yet be listening on port 443 (check NAT and Masquerading rules also).
  • If your web request takes a very long time, and then times out, a firewall blocking traffic on TCP port 443 to the web server.