Wednesday, December 14, 2016

Generating a self-signed certificate for multiple wildcard domains using Subject Alternative Name

Recently I needed to enable HTTPS on several IIS sites on several machines. Some of the sites share part of the domain name and all of them can be accessed by more than one domain:
  • Site A: https://brand1.something2.com
  • Site A: https://brand2.something2.com
  • Site B: https://brand3.something2.com
  • Site B: https://brand4.something2.com
  • Site C: https://brand1.something3.com
  • Site C: https://brand2.something3.com
  • Site D: https://brand3.something3.com
  • Site D: https://brand4.something3.com

and so on...

Please bear in mind that I wanted to use the default (443) port for all of them - otherwise I would need to create a map of ports - taking into account the number of environments involved (more than 100 combinations) it would be impossible to remember them (or at least hard). IIS has a limitation and it allows to bind only one site for IP and port combination if you use HTTPS. It is a classic chicken and egg problem - IIS must be able to know upfront which certificate should be used during SSL handshake but it's impossible because the HTTP request with Host Header inside  (which is needed to determine the domain name and hence the site) hasn't been sent yet. So I needed only one certificate for all of the sites and brands. 
One cert to rule them all...
To do that we need a certificate with SAN - Subject Alternative Name property. Inside we can list all of the domain combinations. To make things simpler we can even use wildcard domains - in case of adding a new brand in the future.

I checked the internet but most of the entries about SAN certificate generation were about OpenSSL which on Windows doesn't work very well (it has a port but poor in my opinion). Then I found out that old makecert tool has been superseded in Windows by a totally new and better tool: PSPKI - Public Key Infrastructure PowerShell module. That was the thing I needed and it saved me a lot of time.

To use the new tool just follow the instruction:
  1. Download PSPKI module from here:
    https://pspki.codeplex.com/
  2. It requires installing Remote Server Administration Tools for Windows.
    If you have Windows 7 use this link:
    https://www.microsoft.com/pl-pl/download/details.aspx?id=7887
    If you have Windows 10 (as I do) use this one:
    https://www.microsoft.com/en-us/download/details.aspx?id=45520
    You can find easily links for other operating systems.
  3. Open PowerShell console with administrative privileges.
  4. Run below script (I added new lines for clarity):
    Import-Module PSPKI
    New-SelfsignedCertificateEx 
    -Subject "CN=*.something1.com" 
    -KeyUsage "KeyEncipherment, DigitalSignature" 
    -SAN "*.something1.com","*.something2.com","*.something3.com","*.something4.com" 
    -ProviderName "Microsoft Software Key Storage Provider" 
    -AlgorithmName ecdsa_p256 
    -KeyLength 256 
    -SignatureAlgorithm sha256 
    -Path c:\SSLCertificate.pfx 
    -Password (ConvertTo-SecureString "password" -AsPlainText -Force) 
    -Exportable
    
Please note that you need to list all of the domains in the SAN parameter as Subject value is ignored if SAN is present in the certificate. I prefer to use the first domain's name in the Subject.

Such certificate can be used in HTTPS bindings of all sites. To avoid browser security errors (apart from Firefox which has its own cert store) you need to install this certificate into Personal and Trusted Root Certification Authorities store on your Local Machine.