The context of the answer is that IIS 7 doesn't actually care about the certificate binding. IIS 7 only ties websites to one or more sockets. Each socket being a combination of IP + port. Source: IIS7 add certificate to site from command line
So, what we want to do is do certificate re-binding on the OS layer. The OS layer takes control of the SSL part, so you use netsh
to associate a certificate with a particular socket. This is done through netsh
using netsh http add sslcert
.
When we bind a (new) certificate to a socket (ip + port), all sites using that socket will use the new certificate.
The command to bind a certificate to a socket is:
netsh http add sslcert ipport=10.100.0.12:443 certhash=1234567890123456789012345678901234567890 appid={12345678-1234-1234-1234-999999999999}
How to
This part explains how to proceed step-by-step. It assumes you have some websites (aaa.my-domain.com, bbb.my-domain.com) running a *.my-domain.com certificate that is about to expire. You already have a new certificate that you already installed on the server but not yet applied to the websites on IIS.
First, we need to find out 2 things. The certhash of your new certificate and the appid.
certhash
Specifies the SHA hash of the certificate. This hash is 20 bytes long and specified as a hexadecimal string.
appid
Specifies the GUID to identify the owning application, which is IIS itself.
Find the certhash
Execute the certutil
command to get all certificates on the machine:
certutil -store My
I need not all information so I do:
certutil -store My | findstr /R "sha1 my-domain.com ===="
Among the output you should find your new certificate ready on your server:
================ Certificate 5 ================
Subject: CN=*.my-domain.com, OU=PositiveSSL Wildcard, OU=Domain Control Validated
Cert Hash(sha1): 12 34 56 78 90 12 34 56 78 90 12 34 56 78 90 12 34 56 78 90
1234567890123456789012345678901234567890
is the certhash
we were looking for. it's the Cert Hash(sha1) without the spaces.
Find the appid
Let's start of by looking at all certificate-socket bindings:
netsh http show sslcert
Or one socket in particular
netsh http show sslcert ipport=10.100.0.12:443
Output:
SSL Certificate bindings:
----------------------
IP:port : 10.100.0.12:443
Certificate Hash : 1111111111111111111111111111111111111111
Application ID : {12345678-1234-1234-1234-123456789012}
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
{12345678-1234-1234-1234-123456789012}
is the appid
we were looking for. It's the Application ID of IIS itself. Here you see the socket 10.100.0.12:443
is currently still bound to the old certificate (Hash 111111111...)
bind a (new) certificate to a socket
Open a command prompt and run it as a administrator. If you don't run it as administrator, you'll get an error like: "The requested operation requires elevation (Run as administrator)."
First remove the current certificate-socket binding using this command
netsh http delete sslcert ipport=10.100.0.12:443
You should get:
SSL Certificate successfully deleted
Then use this command (found here) to add the new certificate-socket binding with the appid and the certhash (without spaces) that you found earlier using this command
netsh http add sslcert ipport=10.100.0.12:443 certhash=1234567890123456789012345678901234567890 appid={12345678-1234-1234-1234-123456789012}
You should get:
SSL Certificate successfully added
DONE. You just replaced the certificate of all websites that are binded to this IP + port (socket).
Best Answer
Generally, a separate IP is required for each SSL site, so if you attempt to bind to the same IP you will see the above error.
This is due to the way SSL works. The server is unable to read the HTTP host header during the handshake process, so it can't use that header information to choose which site (and certificate) to use. Thus certificates in IIS are basically bound per-IP, rather than per-site.
If you have a wildcard certificate or ASN certificate that applies to multiple sites, you can set it up as follows:
appcmd set site /site.name:"<IISSiteName>" /+bindings.[protocol='https',bindingInformation='*:443:<hostHeaderValue>']
Replace and with the appropriate values (Website1 and www.example.com, for example).
SNI is supported in IIS8 to allow multiple unrelated SSL sites on the same IP. Note that SNI is only supported in modern browsers, so it may cause problems for you if you are running a commercial site with a wide audience, like Windows XP users running older versions of Internet Explorer.