AdvancedLesson 9 of 16

SSL/TLS Certificates and HTTPS Binding

TLS 1.3, certificate types (DV/OV/EV/Wildcard/SAN), the Windows certificate store, HTTP.sys SSL bindings via netsh, SNI, HSTS, and the full end-to-end process for deploying and renewing HTTPS on IIS — treated with the depth this critical topic deserves.

🧒 Simple Explanation (ELI5)

SSL/TLS is like a sealed, tamper-evident envelope for your web traffic. When your browser visits https://bank.com, it asks for the bank's identity card (certificate). The bank shows a card stamped by a trusted authority (Certificate Authority). Your browser checks the stamp is real and the card name matches. Then they agree on a secret code (session key) that only they know, and from then on all messages are locked inside sealed envelopes that nobody else can open or fake.

🔧 Why Do We Need It?

🌍 Real-world Analogy

TLS is like international passport verification. The Certificate Authority (CA) is the trusted government that issues passports. The SSL certificate is the website's passport — it proves identity and is verifiable by the CA's public records. The TLS handshake is the border control check: the agent (browser) checks the passport is valid (not expired), issued by a trusted government (root CA in the trust store), and for the right person (cert CN/SAN matches the domain). Once verified, the traveller and agent agree on a shared language only they know (the symmetric session key) for private communication.

⚙️ Technical Explanation

TLS Handshake: when a client connects to port 443, HTTP.sys (which owns the socket in kernel mode) performs the TLS handshake before passing the request to IIS. The handshake negotiates: TLS version (TLS 1.2 or 1.3 in modern environments), cipher suite (AES-GCM is preferred), and the symmetric session key (via ECDH key exchange). The server presents its certificate; the client validates the chain up to a trusted root CA. With TLS 1.3 (available from IIS 10 on Server 2022), the handshake requires only 1 RTT (vs 2 for TLS 1.2) significantly improving first-connection latency.

Certificate Types: DV (Domain Validation) — CA verifies you control the domain (no identity vetting). Fast and cheap, used for most public sites including Let's Encrypt. OV (Organisation Validation) — CA verifies the organisation is real. Browser shows padlock + company name in cert details. Used for corporate sites. EV (Extended Validation) — thorough identity verification. Shows company name in browser address bar (green bar in older browsers). Wildcard (*.example.com) — matches any single subdomain level. Cannot be used for the root domain itself and cannot nest subdomains. SAN (Subject Alternative Name) — one certificate covers multiple specific hostnames (api.example.com, www.example.com, example.com). Required for multi-domain scenarios on a shared IP with SNI.

Windows Certificate Store: Windows maintains certificate stores per computer and per user. IIS uses the Computer\Personal store (also called LocalMachine\My). When a certificate is imported here with its private key, IIS can use it for SSL bindings. The certificate must have the private key attached — IIS cannot use a public-key-only certificate for SSL termination. Certificate thumbprints (SHA-1 hash of the certificate) are used to reference certs in IIS bindings and netsh SSL certificate bindings.

⚠️
The Two-Layer SSL Binding Model in IIS

IIS HTTPS uses TWO binding layers that must both be correct:

  1. IIS Site Binding (stored in applicationHost.config): maps the site to a protocol+IP+port+hostname. Set via IIS Manager → Bindings. Contains the certificate's friendly name or SNI hostname.
  2. HTTP.sys SSL Certificate Binding (kernel-level): maps IP:port (or hostname:port for SNI) to a specific certificate thumbprint + app GUID. Set via netsh or automatically by IIS when you configure the site binding. Viewable with netsh http show sslcert.

Both must be consistent. If you replace a certificate but only update the IIS binding without updating the netsh mapping, the old (possibly expired) certificate continues to be served. Run netsh http show sslcert to verify the thumbprint matches the new certificate after every cert renewal.

📊 Visual Representation

TLS Flow and Certificate Validation
TLS Handshake Steps
1. Client Hello (TLS version, cipher suites, SNI extension)
2. Server Hello (chosen cipher, TLS version)
3. Server Certificate (DER-encoded X.509)
4. Certificate Verify + Finished
5. Encrypted Application Data
Certificate Trust Chain
Server cert (shop.example.com)
↑ signed by
Intermediate CA (DigiCert SHA2)
↑ signed by
Root CA (DigiCert Global Root)
↑ in browser trust store

⌨️ Commands / Syntax

cmd / PowerShell
# === Certificate Store Management ===
# View all certs in the Computer/Personal (LocalMachine\My) store
Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, Thumbprint, NotAfter

# Find certificates expiring within 30 days
Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.NotAfter -lt (Get-Date).AddDays(30)}

# Import a PFX certificate (with private key)
$pfxPass = ConvertTo-SecureString "your-password" -AsPlainText -Force
Import-PfxCertificate -FilePath C:\certs\mysite.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $pfxPass

# Export a certificate with private key (backup)
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*mysite*"}
Export-PfxCertificate -Cert $cert -FilePath C:\backup\mysite.pfx -Password (Read-Host "Password:" -AsSecureString)

# === IIS HTTPS Binding ===
# Add HTTPS binding via PowerShell WebAdministration
Import-Module WebAdministration
$thumbprint = (Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -like "*shop.example.com*"}).Thumbprint
New-WebBinding -Name "Shop" -Protocol https -Port 443 -HostHeader "shop.example.com" -SslFlags 1
(Get-Item "IIS:\Sites\Shop").Bindings.Add("*:443:shop.example.com","Ssl","1","$thumbprint")

# Add binding via appcmd (simpler)
appcmd set site /site.name:"Shop" /+bindings.[protocol='https',bindingInformation='*:443:shop.example.com']
# Then associate cert via netsh:
netsh http add sslcert hostnameport=shop.example.com:443 certhash=THUMBPRINT appid="{4dc3e181-e14b-4a21-b022-59fc669b0914}" certstorename=MY

# === View and manage HTTP.sys SSL cert bindings ===
netsh http show sslcert                     # Show all SSL certificate bindings
netsh http show sslcert ipport=0.0.0.0:443  # Show specific IP:port binding
netsh http delete sslcert ipport=0.0.0.0:443   # Remove binding
netsh http delete sslcert hostnameport=api.example.com:443  # Remove SNI binding

# Update binding to new certificate thumbprint (common after cert renewal)
netsh http delete sslcert hostnameport=shop.example.com:443
netsh http add sslcert hostnameport=shop.example.com:443 ^
  certhash=NEWTHUMBPRINT ^
  appid="{4dc3e181-e14b-4a21-b022-59fc669b0914}" ^
  certstorename=MY

# === Cipher Suite and TLS Version (Windows 2019+) ===
# Check current TLS protocols enabled
Get-TlsCipherSuite | Select-Object Name,Exchange,Cipher,Mac | Format-Table

# Disable TLS 1.0 and 1.1 via Registry (requires reboot)
$base = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols"
New-Item -Path "$base\TLS 1.0\Server" -Force
Set-ItemProperty -Path "$base\TLS 1.0\Server" -Name Enabled -Value 0
New-Item -Path "$base\TLS 1.1\Server" -Force
Set-ItemProperty -Path "$base\TLS 1.1\Server" -Name Enabled -Value 0

💼 Example (Real-world Use Case)

An enterprise IIS server hosts 12 HTTPS sites on one IP using SNI. The operations team needs to renew the *.apps.company.com wildcard certificate before expiry. Process: (1) The CA issues a new wildcard PFX. Import it: Import-PfxCertificate -FilePath new-wildcard.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $pfxPass. (2) Record the new thumbprint from the import output. (3) In IIS Manager, for the 8 sites using the wildcard: edit each HTTPS binding and re-select the certificate — IIS automatically updates the applicationHost.config and re-registers the netsh SSL cert binding. (4) Verify all 8 SNI bindings updated: netsh http show sslcert — confirm all 8 hostname:port entries show the new thumbprint. (5) Use curl -v https://each-site.apps.company.com to confirm the new cert's expiry date is returned. (6) Verify no sites still reference the old cert's thumbprint. (7) Schedule deletion of the old certificate from the store after 30 days for rollback window.

🧪 Hands-on

  1. Create a self-signed certificate for testing: New-SelfSignedCertificate -DnsName "localhost","127.0.0.1" -CertStoreLocation Cert:\LocalMachine\My -FriendlyName "IIS Test SSL" -KeyExportPolicy Exportable. Note the thumbprint in the output.
  2. In IIS Manager → Default Web Site → Bindings → Add: Type HTTPS, IP All Unassigned, Port 443, leave Host name blank, SSL certificate = "IIS Test SSL". Click OK.
  3. Run netsh http show sslcert and find the 0.0.0.0:443 entry. Confirm the certhash matches the thumbprint from step 1. This is your proof that HTTP.sys is bound to the correct certificate.
  4. Browse https://localhost in a browser. Accept the self-signed certificate warning. Confirm the site loads. Click the padlock → Certificate → confirm the CN is "localhost" and the issuer is your machine name (self-signed).
  5. Check for certificates expiring within 60 days: Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.NotAfter -lt (Get-Date).AddDays(60)} | Select-Object Subject, Thumbprint, NotAfter | Format-List. This is the command you add to a monitoring script or scheduled task for proactive cert expiry alerting — catching expiry before it causes a P1 incident.
💡
Certificate Renewal Best Practices

1. Renew 30+ days before expiry — not the day before. CA validation can take hours for OV/EV certs. 2. Import new cert, create the new binding or update netsh, then verify with curl/browser BEFORE removing the old cert. 3. Keep the old cert in the store for 7 days in case rollback is needed. 4. Automate expiry monitoring: a daily script that checks Cert:\LocalMachine\My for certs expiring within 30 days and sends an email alert is essential for any production IIS environment. 5. For Let's Encrypt: use win-acme (WACS) — it automates certificate issuance, renewal, and IIS binding updates on a 60-day cycle with zero manual intervention.

🐛 Debugging Scenario

Failure: A site's SSL certificate was renewed and installed. The browser still shows the old expired certificate.

🎯 Interview Questions

Beginner

What is the difference between SSL and TLS?

SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are cryptographic protocols that secure network communications. SSL 2.0 and 3.0 are deprecated and broken (POODLE, BEAST attacks). TLS is the modern successor: TLS 1.0 (1999), TLS 1.1, TLS 1.2 (2008, still widely used), TLS 1.3 (2018, fastest and most secure — 1-RTT handshake, forward secrecy always on, removed weak ciphers). The term "SSL" is colloquially used for both protocols even when TLS is meant — "SSL certificate" is technically a TLS certificate. For IIS in production: TLS 1.2 minimum is mandatory; TLS 1.3 should be enabled on Windows Server 2022+. Disable SSL 3.0, TLS 1.0, and TLS 1.1 via Windows registry or Group Policy.

What is an SSL certificate and what information does it contain?

An SSL/TLS certificate is a digital document in X.509 format that binds a public key to an identity (domain name or organisation). Key fields: Subject (CN = Common Name = the primary hostname the cert is for), Subject Alternative Names (SANs — additional hostnames the cert is valid for, listed in the extensions), Issuer (the CA that signed the cert), Valid From / Valid To (validity period), Public Key (asymmetric key used in the TLS handshake), Signature (CA's signature proving the cert wasn't tampered with), Key Usage (how the key may be used — Digital Signature for RSA cert). In production: always verify the SAN field covers your hostname — browsers check SANs, not just the CN. Newer certificates only rely on SANs; CN is present but not used for hostname matching in modern browsers.

Where does IIS store SSL certificates on Windows?

IIS uses the Windows Certificate Store, specifically the Local Computer (LocalMachine) Personal store, also called LocalMachine\My in PowerShell. Certs here are accessible to all users and services on the machine, including IIS worker processes. You can view this store in: MMC → Add Snap-in → Certificates → Computer Account → Local Computer → Personal → Certificates. Or in PowerShell: Get-ChildItem Cert:\LocalMachine\My. Certificates must be imported with their private key to the Personal store before IIS can use them for HTTPS. Certificates in other stores (Trusted Root, Intermediate CA) are part of the trust chain but are not used directly for SSL bindings — only Personal store certificates can be selected in IIS site bindings.

What is a certificate thumbprint and how is it used in IIS?

A certificate thumbprint is the SHA-1 hash of the certificate's DER (binary) encoded form, presented as a 40-character hexadecimal string. It is a unique identifier for a specific certificate instance. IIS uses thumbprints in two places: applicationHost.config stores the thumbprint in the site's HTTPS binding configuration. HTTP.sys SSL certificate binding (created via netsh http) uses the thumbprint as certhash to identify which certificate to load for TLS handshakes for a specific IP:port or hostname:port. When you replace a certificate (e.g., renewal), the new certificate has a new thumbprint even if the domain name and key are the same — both the IIS binding and the netsh binding must be updated to reference the new thumbprint.

What is SNI and why is it needed for multiple HTTPS sites on one IP?

SNI (Server Name Indication) is a TLS extension that allows the client to send the desired server hostname during the TLS ClientHello, before the server has sent the certificate. This allows HTTP.sys to know which site's certificate to present for the TLS handshake, even though multiple sites share the same IP address. Without SNI: the server has to commit to one certificate per IP:port combination before reading the HTTP Host header. With SNI: the server reads the SNI extension (client declares "I want shop.example.com") and selects the matching certificate from its store. IIS 8.0 introduced SNI support. In IIS Manager, SNI bindings appear with "Require SNI" checked; in netsh they use hostnameport syntax instead of ipport. All modern browsers support SNI.

Intermediate

How does the Windows SCHANNEL module relate to IIS TLS?

SCHANNEL (Secure Channel) is the Windows security package that implements TLS/SSL protocols. HTTP.sys delegates all TLS handshaking to SCHANNEL — HTTP.sys calls SCHANNEL APIs to negotiate the TLS session, not its own code. SCHANNEL is configured via the Windows registry under HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL. There you can enable/disable specific TLS protocol versions (Protocols\TLS 1.2\Server\Enabled) and cipher suites. Changes to SCHANNEL affect ALL applications using Windows TLS — not just IIS. Tools: IIS Crypto (free) provides a GUI for SCHANNEL settings with pre-built templates for PCI compliance, FIPS compliance, and best practices. Always test SCHANNEL changes on a non-production server — disabling the wrong cipher can break all HTTPS connections platform-wide.

What is HSTS and how do you configure it in IIS?

HSTS (HTTP Strict Transport Security) is an HTTP response header that instructs browsers to always use HTTPS for requests to a domain, even if the user types HTTP or clicks an HTTP link. The browser stores the HSTS policy and automatically upgrades HTTP requests to HTTPS without making an HTTP request first (preventing SSL stripping attacks). Configure in IIS: add the header in web.config: <customHeaders><add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains; preload" /></customHeaders>. Flags: max-age (seconds the policy is stored — typically 1 year = 31536000), includeSubDomains (also applies to all subdomains), preload (allows submission to browser preload lists — permanent HTTPS enforcement even before any connection). Warning: do not set HSTS until you are certain the site will always be HTTPS and all subdomains have valid certs — reversing HSTS is nearly impossible for the max-age period.

What is certificate chain validation and what happens if the intermediate CA is missing?

TLS certificate chain validation is the process by which a browser verifies the server certificate is signed by a trusted CA. The chain goes: Server Cert → signed by → Intermediate CA → signed by → Root CA (in browser trust store). The server must send the full chain (server cert + all intermediates) in the TLS ServerCertificate message. If the intermediate CA certificate is missing: browsers cannot complete chain validation and display "ERR_CERT_AUTHORITY_INVALID" or "Certificate chain incomplete." On IIS: after importing a PFX, verify the chain exists in the store — the intermediate CA cert should appear in the LocalMachine\Intermediate Certification Authorities store. If missing: download the intermediate cert from the CA's AIA (Authority Information Access) URL embedded in the server cert, install it to the Intermediate CA store. Test chain: certutil -verify C:\certs\mysite.cer or use the SSL Labs Server Test.

How do you configure IIS to redirect all HTTP traffic to HTTPS?

Two methods: (1) IIS HTTP Redirect module: Site → HTTP Redirect (in IIS Manager) → enable "Redirect requests to this destination: https://$(SERVER_NAME)$(REQUEST_URI)" — however this requires careful configuration to avoid redirect loops for secure sites and doesn't pass the path properly by default. (2) URL Rewrite (preferred): requires URL Rewrite module installed. Add rule in web.config: <rules><rule name="HTTP to HTTPS" enabled="true" stopProcessing="true"><match url="(.*)" /><conditions><add input="{HTTPS}" pattern="off" ignoreCase="true" /></conditions><action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /></rule></rules>. The condition checks if the incoming connection is NOT HTTPS; if so, redirects with 301 Permanent. Combine with HSTS header to prevent the initial HTTP connection in future visits.

What is the difference between a SHA-1 and SHA-256 certificate and why does it matter?

SHA-1 and SHA-256 refer to the hashing algorithm used to sign the certificate. SHA-1 was deprecated by all major browsers and CAs from 2017 onwards because theoretical collision attacks were demonstrated. Any SHA-1 signed certificate is rejected by modern browsers with a security error regardless of validity. SHA-256 (part of the SHA-2 family) is the current standard — certificates should be issued with SHA-256 or SHA-384 signature. Key ID fingerprints in newer certificates use SHA-256. For IIS deployments: always ensure the certificate was issued with SHA-256 signature. The chain (intermediate CA cert) must also be SHA-256 — a SHA-256 server cert with a SHA-1 intermediate CA may still cause browser warnings. Use SSL Labs full chain test to verify all chain certificates use SHA-256.

Scenario-based

A user reports the site shows "Your connection is not private" in Chrome. You just renewed the cert. What do you check?

Systematic check: 1. netsh http show sslcert hostnameport=mysite.example.com:443 — verify certhash matches the thumbprint of the new certificate. If it shows the old (expired) thumbprint: IIS Manager may have updated applicationHost.config but netsh binding was not re-created. Manually delete and re-add. 2. Get-ChildItem Cert:\LocalMachine\My | Where {$_.Thumbprint -eq "newthumb"} | Select NotAfter, Subject — confirm the new cert is actually present in the store and has a valid future expiry. 3. Check the certificate chain: is the intermediate CA cert present in LocalMachine\Intermediate? Missing intermediate = chain error. 4. Check SAN: does the cert's Subject Alternative Names include the hostname the user is accessing? A wildcard cert for *.example.com does NOT cover the root example.com. 5. Check the hostname in the browser matches what the cert was issued for — a common issue when a site moves to a new domain.

IIS is serving the wrong certificate for a site (showing a different site's cert). How is this possible and how do you fix it?

This is an SNI misconfiguration or binding conflict. Causes: 1. The site's HTTPS binding does not have SNI enabled (Require SNI unchecked). HTTP.sys falls back to the default IP:port binding (*:443 or 0.0.0.0:443) which serves a different certificate. Fix: edit the binding → check "Require Server Name Indication" → select the correct certificate. 2. Two sites have an HTTPS binding for the same hostname:port but different certs — HTTP.sys uses the first one in its internal table. Fix: remove the duplicate binding from the incorrect site. 3. The netsh SSL cert binding for this hostname:port has the wrong certificate thumbprint — points to a different cert. Fix: delete and re-add with the correct thumbprint. 4. Intermediate SSL termination (load balancer, WAF, CDN) is serving a cached/outdated certificate. Test directly on the server (curl -v --resolve "mysite:443:127.0.0.1" https://mysite) to bypass the intermediary and confirm what IIS actually sends.

After disabling TLS 1.0 on the server, some older clients can no longer connect. How do you handle this?

This is a compatibility vs security conflict. Assessment: identify which clients are failing (check IIS logs for SCHANNEL handshake errors matching client IPs, or enable SCHANNEL event logging under Event Viewer). Common old clients requiring TLS 1.0: IE on Windows XP, old Java applications (.NET clients below 4.5 default to TLS 1.0), embedded devices, old banking middleware. Options: 1. If the old clients are internal enterprise machines: enforce OS/browser upgrades. Windows XP is EOL — this is also a serious security risk beyond TLS. 2. If external users on old browsers: document the impact, set a deprecation timeline, notify users. 3. If it's a critical business integration: enable TLS 1.1 as a temporary bridge (better than TLS 1.0, still not PCI compliant). 4. Deploy a separate IIS endpoint with TLS 1.0 enabled only for the specific integration, while keeping TLS 1.2+ on public endpoints. Never re-enable TLS 1.0 globally — isolate the exception.

Your IIS server has 20 HTTPS sites and certificate renewal is managed manually, causing recurring expired cert incidents. How do you automate this?

Automate with win-acme (WACS — Windows ACME Simple): (1) Install WACS from https://www.win-acme.com. (2) Run wacs.exe — it detects IIS sites and prompts for domain selection. (3) It issues a Let's Encrypt certificate (or integrates with your CA via ACME protocol), installs it to the Windows certificate store, creates/updates IIS bindings, and creates the netsh SSL cert binding. (4) WACS creates a Windows Scheduled Task that runs every 60 days to auto-renew. For enterprise internal CAs (Active Directory Certificate Services): use the CertEnroll API or PowerShell ADCS module to automate CSR generation, submission to internal CA, and certificate installation. Add a monitoring script: daily check of all certs in LocalMachine\My, alert 30 days before expiry via email/Teams webhook. Track all certificates in a CMDB with owner, renewal date, and responsible team — incident-free cert management requires both automation and visibility.

Explain how you would set up a Central SSL Certificate Store for an IIS server farm.

Central Certificate Store (CCS) is an IIS 8+ feature that reads certificates from a UNC file share instead of the local Windows certificate store. Setup: 1. Create a file share on a highly available server (\\certstore\certs). Grant the UNC share Read access to all IIS server computer accounts. 2. Name certificates using the hostname they are for: www.example.com.pfx (IIS reads the filename to match the hostname). 3. In IIS Manager on each server → Central Certificate Store → Enable → set the UNC path, account for reading the share, and the certificate file password. 4. When creating site bindings: select "Use Centralized SSL Certificate Store" instead of selecting a cert directly. IIS automatically reads the correct .pfx file from the share based on the binding hostname. Benefit: renewing a certificate requires only uploading the new .pfx to the file share — all IIS servers in the farm immediately use the new certificate without any per-server changes. Critical: the file share must be highly available — all HTTPS connections fail if IIS cannot access the CCS share.

🌐 Real-world Usage

SSL/TLS is non-negotiable in production — every public-facing IIS site must have a valid, properly configured HTTPS binding. SSL configuration errors (expired certs, wrong thumbprint, missing intermediate CA, TLS 1.0 disabled breaking clients) are among the highest-frequency and highest-impact incidents in IIS environments. Engineers with deep SSL knowledge can diagnose and resolve these incidents in minutes while others spend hours.

📝 Summary

IIS SSL uses two binding layers: applicationHost.config (IIS site binding) and HTTP.sys kernel-level binding (netsh). Both must reference the current certificate thumbprint for HTTPS to work correctly after cert renewal. Certificates live in the Windows LocalMachine\My store with private key. Use SNI for multi-site HTTPS on one IP. Disable TLS 1.0/1.1 for PCI compliance. Automate renewal with win-acme or ADCS to eliminate cert-expiry incidents.