PFX/PKCS12 Certificate Management Guide

This guide provides comprehensive instructions for managing SSL/TLS certificates in PFX (PKCS12) format, including extraction, verification, and conversion to formats commonly used by web servers like Nginx, Apache, and Traefik.

Prerequisites

  • OpenSSL installed on your system
  • Access to your PFX file
  • Password for the PFX file (if protected)

Understanding PFX Files

What is a PFX file?

PFX (Personal Information Exchange) or PKCS#12 is a binary format that bundles:

  • Private Key – Used to decrypt traffic
  • Certificate – Your domain/server certificate (leaf certificate)
  • Certificate Chain – Intermediate and optionally root CA certificates

Why extract components from PFX?

Many web servers and applications require certificates in PEM format with separate or combined files:

  • Nginx: Requires fullchain.pem and privkey.pem
  • Apache: Requires certificate, private key, and chain as separate files
  • Traefik: Can use either PFX or PEM formats
  • HAProxy: Requires combined certificate + key file
  • Docker containers: Often expect PEM format

Common Use Cases

  1. Setting up SSL/TLS on web servers (Nginx, Apache, Traefik)
  2. Migrating certificates between different platforms
  3. Verifying certificate chain completeness before deployment
  4. Converting Windows-exported certificates to Linux-compatible format
  5. Troubleshooting SSL certificate issues

Working with PFX Files

Setup Environment

First, set your PFX password as an environment variable for convenience:

export PFX_PASSWORD='your_password_here'

Note: For empty passwords, use: export PFX_PASSWORD=''

Check if PFX Contains Full Chain

Before extracting, verify that your PFX file contains the complete certificate chain.

Method 1: Count Certificates

openssl pkcs12 -in star.yourfile.pfx -nodes -nokeys -passin pass:$PFX_PASSWORD | grep -c "BEGIN CERTIFICATE"

Expected Results:

  • 1 = Only your certificate (⚠️ incomplete chain)
  • 2 = Your certificate + 1 intermediate CA (✅ typical)
  • 3+ = Your certificate + multiple intermediates (✅ complete chain)

Method 2: Display Certificate Details

openssl pkcs12 -in star.yourfile.pfx -nodes -nokeys -passin pass:$PFX_PASSWORD -info

This command displays:

  • All certificates with their subject and issuer
  • Certificate validity dates
  • Complete certificate chain hierarchy

Extract Components from PFX

Extract Full Certificate Chain (fullchain.pem)

This creates a file containing your certificate and all intermediate certificates.

openssl pkcs12 -in star.yourfile.pfx -out star.yourfile.pem -nodes -nokeys -passin pass:$PFX_PASSWORD

Flags Explained:

  • -in – Input PFX file
  • -out – Output PEM file
  • -nodes – Don’t encrypt the output (removes passphrase)
  • -nokeys – Export only certificates, not the private key
  • -passin pass:$PFX_PASSWORD – Provide password non-interactively

Output: star.yourfile.pem (fullchain.pem)

Extract Private Key (privkey.pem)

This extracts only the private key from the PFX file.

openssl pkcs12 -in star.yourfile.pfx -out star.yourfile.key -nodes -nocerts -passin pass:$PFX_PASSWORD

Flags Explained:

  • -nocerts – Export only the private key, not certificates
  • -nodes – Output key without encryption

Output: star.yourfile.key (privkey.pem)

⚠️ Security Warning: Protect this file! Set proper permissions:

chmod 600 star.yourfile.key

Extract Everything in One File

If you need certificate + chain + private key in a single file:

openssl pkcs12 -in star.yourfile.pfx -out combined.pem -nodes -passin pass:$PFX_PASSWORD

Use Case: HAProxy, some load balancers

Verification Methods

1. View Certificate Subjects and Issuers

openssl crl2pkcs7 -nocrl -certfile star.yourfile.pem | openssl pkcs7 -print_certs -noout

What to look for:

  • Each certificate’s subject should match the next certificate’s issuer
  • Forms a chain from your certificate to the root CA

Example Output:

subject=CN=*.example.com
issuer=CN=Intermediate CA

subject=CN=Intermediate CA
issuer=CN=Root CA

2. Verify Certificate Chain Integrity

openssl verify -CAfile star.yourfile.pem star.yourfile.pem

Expected Output:

star.yourfile.pem: OK

If verification fails, your chain is incomplete or corrupted.

3. Check Certificate Expiration

openssl x509 -in star.yourfile.pem -noout -dates

Output:

notBefore=Jan  1 00:00:00 2024 GMT
notAfter=Dec 31 23:59:59 2025 GMT

4. Display Certificate Details

openssl x509 -in star.yourfile.pem -text -noout

Shows complete certificate information including:

  • Subject and Issuer
  • Validity period
  • Subject Alternative Names (SANs)
  • Key usage
  • Extensions

5. List All Certificates in Chain

openssl storeutl -certs star.yourfile.pem

Displays each certificate in the chain with its details.

Creating Full Chain Certificates

Scenario 1: PFX Missing Intermediate Certificates

If your PFX only contains the leaf certificate, you need to add the chain manually.

Step 1: Extract components

# Extract certificate
openssl pkcs12 -in star.yourfile.pfx -out cert.pem -nodes -nokeys -clcerts -passin pass:$PFX_PASSWORD

# Extract private key
openssl pkcs12 -in star.yourfile.pfx -out privkey.pem -nodes -nocerts -passin pass:$PFX_PASSWORD

Step 2: Obtain intermediate certificates

Download the chain file from your Certificate Authority (CA):

  • Let’s Encrypt: Included automatically
  • DigiCert, Sectigo, etc.: Available in your CA account
  • Or download from: https://www.example-ca.com/chain.pem

Step 3: Combine certificate with chain

cat cert.pem chain.pem > fullchain.pem

Step 4: Create new PFX with complete chain

openssl pkcs12 -export -out newfile.pfx \
  -inkey privkey.pem \
  -in cert.pem \
  -certfile chain.pem \
  -name "*.example.com" \
  -passout pass:$PFX_PASSWORD

Scenario 2: Already Have Separate Files

If you have certificate and chain as separate files:

# Combine certificate and chain
cat star_asb_bh.crt star_asb_bh-chain.pem > fullchain.pem

# Verify the chain
grep -c "BEGIN CERTIFICATE" fullchain.pem
openssl verify -CAfile fullchain.pem fullchain.pem

Optional: Create PFX from separate files:

openssl pkcs12 -export -out newfile.pfx \
  -inkey star_asb_bh.key \
  -in star_asb_bh.crt \
  -certfile star_asb_bh-chain.pem \
  -name "*.asb.bh" \
  -passout pass:$PFX_PASSWORD

Alternative Scenarios

Using with Nginx

Create the required files:

# Full chain certificate
openssl pkcs12 -in star.yourfile.pfx -out /etc/nginx/ssl/fullchain.pem -nodes -nokeys -passin pass:$PFX_PASSWORD

# Private key
openssl pkcs12 -in star.yourfile.pfx -out /etc/nginx/ssl/privkey.pem -nodes -nocerts -passin pass:$PFX_PASSWORD

# Set permissions
chmod 644 /etc/nginx/ssl/fullchain.pem
chmod 600 /etc/nginx/ssl/privkey.pem

Nginx configuration:

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
}

Using with Traefik

Option 1: Use PFX directly (if Traefik supports it)

tls:
  stores:
    default:
      defaultCertificate:
        certFile: /path/to/star.yourfile.pfx

Option 2: Convert to PEM format

# Extract both cert and key
openssl pkcs12 -in star.yourfile.pfx -out combined.pem -nodes -passin pass:$PFX_PASSWORD

Traefik configuration:

tls:
  certificates:
    - certFile: /path/to/fullchain.pem
      keyFile: /path/to/privkey.pem

Using with Apache

# Certificate
openssl pkcs12 -in star.yourfile.pfx -out /etc/apache2/ssl/cert.pem -nodes -nokeys -clcerts -passin pass:$PFX_PASSWORD

# Private Key
openssl pkcs12 -in star.yourfile.pfx -out /etc/apache2/ssl/privkey.pem -nodes -nocerts -passin pass:$PFX_PASSWORD

# Chain (intermediate certificates)
openssl pkcs12 -in star.yourfile.pfx -out /etc/apache2/ssl/chain.pem -nodes -nokeys -cacerts -passin pass:$PFX_PASSWORD

Apache configuration:

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/cert.pem
    SSLCertificateKeyFile /etc/apache2/ssl/privkey.pem
    SSLCertificateChainFile /etc/apache2/ssl/chain.pem
</VirtualHost>

Troubleshooting

Error: “wrong tag” or “nested asn1 error”

Cause: Corrupted file, wrong format, or legacy encryption

Solutions:

# Try with legacy provider (OpenSSL 3.x)
openssl pkcs12 -in star.yourfile.pfx -nodes -nokeys -legacy -passin pass:$PFX_PASSWORD

# Try with both providers
openssl pkcs12 -in star.yourfile.pfx -nodes -nokeys -provider legacy -provider default -passin pass:$PFX_PASSWORD

Error: File shows all zeros (0x00)

Check file integrity:

hexdump -C star.yourfile.pfx | head -20

Valid PFX should start with: 30 82 or 30 80 or 30 84

If all zeros: File is corrupted. Re-download or re-export from source.


Error: “MAC verification failed”

Cause: Incorrect password

Solution:

  • Verify your password
  • Try empty password: export PFX_PASSWORD=''
  • Re-export the PFX with known password

Certificate Chain Verification Fails

Check the chain order:

openssl storeutl -certs fullchain.pem

Expected order:

  1. Your domain certificate (leaf)
  2. Intermediate CA certificate(s)
  3. Root CA (optional)

Fix incorrect order:

# Manually reorder certificates in a text editor
# Ensure leaf certificate comes first

Missing Intermediate Certificates

Symptoms:

  • Browser shows “NET::ERR_CERT_AUTHORITY_INVALID”
  • SSL Labs test shows “Chain issues”
  • grep -c "BEGIN CERTIFICATE" returns only 1

Solution: Download intermediate certificate from your CA and combine:

cat your-cert.pem intermediate.pem > fullchain.pem

Quick Reference Commands

# Set password
export PFX_PASSWORD='your_password'

# Check certificate count
openssl pkcs12 -in file.pfx -nodes -nokeys -passin pass:$PFX_PASSWORD | grep -c "BEGIN CERTIFICATE"

# Extract full chain
openssl pkcs12 -in file.pfx -out fullchain.pem -nodes -nokeys -passin pass:$PFX_PASSWORD

# Extract private key
openssl pkcs12 -in file.pfx -out privkey.pem -nodes -nocerts -passin pass:$PFX_PASSWORD

# Verify chain
openssl verify -CAfile fullchain.pem fullchain.pem

# View certificate details
openssl x509 -in fullchain.pem -text -noout

# Check expiration
openssl x509 -in fullchain.pem -noout -dates

# Create PFX from separate files
openssl pkcs12 -export -out new.pfx -inkey privkey.pem -in cert.pem -certfile chain.pem

# Combine certificate files
cat cert.pem chain.pem > fullchain.pem

Security Best Practices

  1. Protect Private Keys

    chmod 600 privkey.pem
    chown root:root privkey.pem
    
  2. Never commit certificates to version control

    # Add to .gitignore
    *.pfx
    *.pem
    *.key
    *.crt
    
  3. Use strong passwords for PFX files

    • Minimum 12 characters
    • Mix of letters, numbers, symbols
  4. Regularly rotate certificates

    • Monitor expiration dates
    • Automate renewal where possible
  5. Store backups securely

    • Encrypted storage
    • Access control
    • Regular backup verification

Additional Resources


License

This documentation is provided as-is for educational and reference purposes.


Last Updated: January 2026

How to Use Let’s Encrypt on Windows Server with IIS

This guide explains how to enable a FREE SSL certificate using Let’s Encrypt on a Windows Server running IIS. Specifically, it addresses the challenges of using wildcard certificates for multiple websites with different domains and subdomains.

Scenario:

You have a Windows Server 2019 with IIS 10, a single IP address, and multiple HTTPS websites hosted with different domain names. For subdomains under the same primary domain (like *.example.com), a wildcard certificate works perfectly. However, complications arise when adding websites from different domains, such as mydomain.com.

Initial Setup Example:

IIS 10 hosts the following sites:

  • ABC Server (Website)
    • abc.api.example.com – HTTPS @ 443
  • ABC Client (Website)
    • abc.example.com – HTTPS @ 443
    • bcd.example.com – HTTPS @ 443
    • cde.example.com – HTTPS @ 443
    • admin.example.com – HTTPS @ 443
  • XYZ App (Website)
    • xyz.example.com – HTTPS @ 443
  • SEQ (Website)
    • seq.mydomain.com – HTTPS @ 443

Managing these SSL certificates with multiple domain names can be tricky, but Let’s Encrypt simplifies the process.

Steps to Enable Let’s Encrypt SSL on IIS

  • Enable IIS and Create the .well-known Folder
    • Follow this guide to create the .well-known directory for SSL validation
      • Create a folder on the C drive named well-known. Inside, create another folder called pki-validation. Example: C:\well-known\pki-validation.
      • Place the required validation file in the pki-validation folder.
      • Open IIS Manager and for each site, right-click and select Add Virtual Directory.
      • In the Alias field, enter .well-known. In the Physical Path field, enter the path to the folder you created, e.g., C:\well-known\pki-validation.
      • Confirm with OK. The folder and files should now be accessible via the web.
  • Set Proper Permissions for the C:\well-known\pki-validation Folder
    • Follow this IIS 403 Forbidden solution:
      • Right-click the .well-known folder and select Properties.
      • Navigate to the Security tab.
      • Click Edit and ensure IIS_IUSRS is listed. If not, click Add
      • In the Enter the object names box, type IIS_IUSRS and click OK.
      • Set Read & execute, List folder contents, and Read permissions for IIS_IUSRS.
  • Validate DNS Entries for Each Domain/Subdomain
    • Use a tool like Google Dig to validate DNS entries for the following domains:
      • abc.api.example.com
      • abc.example.com
      • bcd.example.com
      • cde.example.com
      • admim.example.com
      • xyz.example.com
      • seq.mydomain.com
  • Download and Install win-acme
    • Download win-acme from https://www.win-acme.com.
    • After downloading, unblock the files and extract them to C:\win-acme.
  • Run win-acme to Generate SSL Certificates
    • Navigate to C:\win-acme and run win-acme.exe as Administrator.
    • Follow the prompts to select the appropriate site for which you want to generate the SSL certificate.
    • Once complete, your sites will be secured with Let’s Encrypt SSL certificates.

By following these steps, you can manage multiple websites with different domains and subdomains on a single IIS server with Let’s Encrypt SSL certificates, solving the issues typically associated with wildcard certificates for different domains.

Other Resources