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
.pfxor.p12 - OpenSSL-based server doesn't accept PFX format
- Error:
PEM routines:no start linewhen 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
-nodesflag - 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
-nodesflag 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
Related Issues
- SSL Private Key Mismatch
- SSL Certificate Chain Incomplete
- SSL Certificate Not Trusted
- OpenSSL Certificate Verify Failed