Introduction

PFX (PKCS#12) format certificates are commonly used on Windows systems and IIS servers. When migrating to Linux servers using Nginx, Apache, or other OpenSSL-based applications, you need to convert to PEM format. The PFX file contains the certificate, private key, and often the certificate chain in one encrypted container - extracting these components correctly is essential.

Symptoms

  • Need to install Windows/IIS certificate on Linux server
  • Certificate file ends with .pfx or .p12
  • OpenSSL-based server doesn't accept PFX format
  • Error: PEM routines:no start line when loading PFX
  • Need separate certificate and key files from single PFX
  • Java keystore certificate needs to work on web server
  • Certificate import asks for PFX password

Common Causes

  • Certificate exported from Windows/IIS in PFX format
  • Certificate from Java keystore exported as PKCS#12
  • Windows Certificate Manager export creates PFX by default
  • Application requires PEM format (Nginx, Apache, HAProxy)
  • Need to extract components separately from combined PFX
  • PFX password unknown or forgotten

Step-by-Step Fix

Step 1: Extract Certificate from PFX

```bash # Extract certificate (public portion) openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.pem

# If PFX has password, you'll be prompted # Or specify password: openssl pkcs12 -in certificate.pfx -clcerts -nokeys -passin pass:yourpassword -out certificate.pem

# The -clcerts flag extracts only client certificates # The -nokeys flag excludes private keys ```

Step 2: Extract Private Key from PFX

```bash # Extract private key openssl pkcs12 -in certificate.pfx -nocerts -nodes -out private.key

# -nocerts: exclude certificates # -nodes: no DES encryption (output unencrypted key)

# If you want encrypted key output: openssl pkcs12 -in certificate.pfx -nocerts -out private-encrypted.key # Key will be encrypted, prompted for new password

# Extract and encrypt with specific password: openssl pkcs12 -in certificate.pfx -nocerts -passout pass:newpassword -out private.key ```

Step 3: Extract Certificate Chain from PFX

```bash # Extract all certificates (including CA chain) openssl pkcs12 -in certificate.pfx -nokeys -out fullchain.pem

# Or extract just CA certificates openssl pkcs12 -in certificate.pfx -cacerts -nokeys -out chain.pem

# -cacerts: extract CA certificates only ```

Step 4: Extract Everything at Once

```bash # Extract all components openssl pkcs12 -in certificate.pfx -nodes -out all.pem

# This creates a file with: # - Private key # - Server certificate # - CA chain certificates

# Then split them manually if needed: # Private key: between PRIVATE KEY markers # Certificates: between CERTIFICATE markers ```

Step 5: Split Combined PEM File

```bash # If you have all.pem with everything, split it:

# Extract private key awk '/-----BEGIN PRIVATE KEY-----/,/-----END PRIVATE KEY-----/' all.pem > private.key

# Extract server certificate (first cert) awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' all.pem | head -n $(awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' all.pem | grep -n "END CERTIFICATE" | head -1 | cut -d: -f1) > server.crt

# Extract chain (remaining certs) awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' all.pem | tail -n +$(awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' all.pem | grep -n "END CERTIFICATE" | head -1 | cut -d: -f1 | awk '{print $1+1}') > chain.crt ```

Step 6: Verify Extracted Files

```bash # Verify certificate openssl x509 -in certificate.pem -noout -text

# Verify private key openssl rsa -in private.key -check

# Verify key matches certificate openssl x509 -noout -modulus -in certificate.pem | openssl md5 openssl rsa -noout -modulus -in private.key | openssl md5 # Hashes must match

# Check certificate chain openssl verify -CAfile chain.pem certificate.pem ```

Step 7: Handle Password-Protected PFX

```bash # If you forgot PFX password, cannot extract # Try common passwords or contact original administrator

# If you have password but it's complex: openssl pkcs12 -in certificate.pfx -info -nokeys -passin pass:password

# Check PFX content without extracting: openssl pkcs12 -in certificate.pfx -info -noout -passin pass:password ```

Step 8: Convert PEM Back to PFX

```bash # If you need to reverse the process (create PFX from PEM) openssl pkcs12 -export -out certificate.pfx \ -inkey private.key \ -in certificate.pem \ -certfile chain.pem

# You'll be prompted for export password # Or specify: openssl pkcs12 -export -out certificate.pfx \ -inkey private.key \ -in certificate.pem \ -passout pass:exportpassword ```

Step 9: Use Extracted Files in Web Server

```nginx # Nginx configuration with extracted PEM files server { listen 443 ssl; server_name example.com;

ssl_certificate /etc/ssl/certs/certificate.pem; ssl_certificate_key /etc/ssl/private/private.key;

# If chain separate: # Combine cert and chain for fullchain # cat certificate.pem chain.pem > fullchain.pem # ssl_certificate /etc/ssl/certs/fullchain.pem; } ```

```apache # Apache configuration <VirtualHost *:443> ServerName example.com SSLEngine on

SSLCertificateFile /etc/ssl/certs/certificate.pem SSLCertificateKeyFile /etc/ssl/private/private.key SSLCertificateChainFile /etc/ssl/certs/chain.pem </VirtualHost> ```

Step 10: Secure the Private Key

```bash # Set correct permissions on extracted key chmod 600 private.key chown root:root private.key

# Or specific web server user chown www-data:www-data private.key # Apache on Debian chown nginx:nginx private.key # Nginx on some systems

# Verify permissions ls -la private.key ```

Common Pitfalls

  • Forgetting PFX password (cannot recover without it)
  • Extracting encrypted key without -nodes flag
  • Not extracting chain certificates separately
  • Private key file permissions too open
  • Using wrong certificate from multi-cert PFX
  • Not verifying key matches certificate after extraction
  • Chain file empty when PFX didn't contain chain

Best Practices

  • Document PFX password when exporting from Windows
  • Use -nodes flag for unencrypted key output
  • Extract chain certificates for complete trust
  • Verify key/cert match after extraction
  • Set strict permissions on private key (600)
  • Keep original PFX as backup
  • Test extracted files before deploying
  • SSL Private Key Mismatch
  • SSL Certificate Chain Incomplete
  • SSL Certificate Not Trusted
  • OpenSSL Certificate Verify Failed