Install a TLS certificate on IIS

IIS imports TLS certificates as PKCS#12 archives, so PEM files must be bundled first — `openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile chain.crt`. Import through the IIS Manager server-level *Server Certificates* feature, then bind it to the site under *Bindings*. If the import rejects a password you know is correct, re-export with `-legacy`, because OpenSSL 3 encrypts archives with AES-256-CBC and the older Windows importer cannot read it.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

Step 1 — build the PFX #

IIS does not read PEM. Bundle first:

Certificate, key and chain into one archive
openssl pkcs12 -export \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile chain.crt \
-name "example.com"

Setting -name matters here — it becomes the friendly name shown in the IIS certificate list, and an unnamed entry is hard to identify later.

Step 2 — import #

IIS Manager: select the server node (not the site), open Server Certificates, then Import… in the Actions pane. Choose the PFX, enter the password, and leave the certificate store as Personal.

Or in PowerShell:

$password = Read-Host -AsSecureString -Prompt "PFX password"
Import-PfxCertificate -FilePath C:\certs\certificate.pfx `
-CertStoreLocation Cert:\LocalMachine\My `
-Password $password

Step 3 — bind it to the site #

Select the site, Bindings…, then Add or Edit:

  • Type: https
  • Port: 443
  • Host name: example.com
  • Require Server Name Indication: tick this if the server hosts more than one HTTPS site
  • SSL certificate: the friendly name you set with -name

Or in PowerShell:

$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*example.com*" }

New-IISSiteBinding -Name "Default Web Site" `
-BindingInformation "*:443:example.com" `
-Protocol https `
-CertificateThumbPrint $cert.Thumbprint `
-CertStoreLocation "Cert:\LocalMachine\My" `
-SslFlag "Sni"

Step 4 — verify #

From any machine with OpenSSL
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| grep "Verify return code"
Expected output
Verify return code: 0 (ok)
Confirm the intermediate is being sent
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null \
| grep -c "BEGIN CERTIFICATE"
Expected output
2

A count of 1 means the intermediate did not make it into the certificate store. Import it separately into Local Machine → Intermediate Certification Authorities.

Exporting a certificate out of IIS #

To move an identity elsewhere, export it with its key and unpack it:

$password = Read-Host -AsSecureString -Prompt "Export password"
Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*example.com*" } |
Export-PfxCertificate -FilePath C:\certs\export.pfx -Password $password

Then on the destination, convert PFX to PEM.

Common IIS problems #

Symptom Cause Fix
“The password you entered is incorrect” OpenSSL 3 AES archive Re-export with -legacy
Certificate missing from the bindings list Imported to the wrong store, or key not present Import to Local Machine → Personal
Chain incomplete for clients Intermediate not in the store Use -certfile, or import it separately
Binding conflict on port 443 Another site holds the binding without SNI Enable SNI on both bindings
Certificate works locally, fails externally Firewall, or the wrong binding hostname Check the host name on the binding

Frequently asked questions

Why does IIS reject a password I know is correct?
Because the archive uses AES-256-CBC, which the older Windows importer cannot decrypt — and it reports every decryption failure as a wrong password. Re-export with -legacy. See the full explanation.
Where does the certificate physically go?
Into the Windows certificate store, normally Local Machine → Personal, not into a file on disk. You can inspect it with certlm.msc or the PowerShell Cert:\\LocalMachine\\My drive.
How do I host several HTTPS sites on one IP?
Tick "Require Server Name Indication" on each binding. SNI has been supported since IIS 8 and Windows Server 2012 and lets each hostname present its own certificate.
Does IIS need the intermediate certificates?
Yes, and they must be in the certificate store rather than a chain file. Including them with -certfile when building the PFX puts them there during the import.

References