Replace ADFS certificate

Replacing the ADFS certificate can be a painful process.

I have learned it the hard way, that's why i thought; let make a thread for this on my blog, for future reference and to help others out.

 

Let's go!

 

Import certificates


First import the certificates on your ADFS server(s) and import hem also on your WAP servers (if you have any).

Notice: you must also import all the certificates in the chain (intermediates; see green checkmarks) except for the ROOT certificate (unless you haven't' in your computer store; but usually all globally trusted root CA's are in your computer certificate store.

To easily import the service communication certificate; use the following cmdlet:

Import-PfxCertificate -FilePath C:\certs\mycert.pfx -CertStoreLocation 'cert:\localmachine\my' -Password $(Read-Host "PFX File Password -AsSecureString)




Step one; open the certificate and click on Install Certificate


Then select the Local Machine as store location



Let the wizard automatically choose the store based on the type of certificate


And complete everything as a whole


The prompt after clicking Finish :)


Repeat the above steps for all certificates that are needed
    1. the ADFS certificate
    2. needed intermediates that the ADFS certificate rely on


 

Set permissions


After everything is imported correctly; you must set the correct permissions for the service account that is used by ADFS.
You can verify it, by looking in services.msc for the ADFS service, it is probably running under a specific user. That uses must have access to the private key.


Open Windows+R and type mmc and press enter.
After that, add the certificates snap-in



Choose Certificates and click Add



Select Computer account



Open folder Personal\Certificates and right-click on the certificate that should be used. Select All Tasks\Manage Private Keys



Set the permissions accordingly the picture below for your service account that ADFS wil use.


 

Replacing the certificates on the ADFS server(s).


Get hold of the current SSL thumbprint AND the SSL thumbprint of your new certificate.

Open Powershell with Elevated permissions and use the cmd-let:

dir cert:\localmachine\my





Check and make a note what the current certificate thumbprint that is in use and what the new certificate thumbprint is; that way we can make sure that we aren't replacing it with the same one that is installed right now :)

With the following cmd-let you can see what the current certificate is, that is used by ADFS:

Get-AdfsSslCertificate




Also check what the thumbprint is that is bonded via HTTP.sys; look for the Certificate Hash.




Here is the output

PS H:\> Get-AdfsSslCertificate

HostName                           PortNumber  CertificateHash
--------                           ----------  ---------------
sts.domain.com                     443         400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0
localhost                          443         400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0
sts.domain.com                     49443       400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0


PS H:\> dir cert:\localmachine\my


    Directory: Microsoft.PowerShell.Security\Certificate::localmachine\my


Thumbprint                                Subject
----------                                -------
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  CN=SERVER, CN=6bXXXXXX-1234-XXXXXXXX-XXXXXXXXXXXX, OU=Microsoft ADFS Agent
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  CN=SERVER, CN=6bXXXXXX-1234-XXXXXXXX-XXXXXXXXXXXX, OU=Microsoft ADFS Agent
400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0  CN=sts.domain.com, OU=PositiveSSL Multi-Domain, OU=Domain Control Validated
100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904  CN=sts.domain.com, <output omitted>


PS H:\> netsh http show sslcert

SSL Certificate bindings:
-------------------------

    Hostname:port                : sts.domain.com l:443
    Certificate Hash             : 400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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               : AdfsTrustedDevices
    DS Mapper Usage              : Disabled
    Negotiate Client Certificate : Disabled

    Hostname:port                : localhost:443
    Certificate Hash             : 400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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               : AdfsTrustedDevices
    DS Mapper Usage              : Disabled
    Negotiate Client Certificate : Disabled

    Hostname:port                : sts.domain.com :49443
    Certificate Hash             : 400323XXXXMY_OLD_THUMBPRINTXXXXX4D07B5C0
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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 : Enabled


PS H:\>



Now we know what are starting point is and what thumbprints are used.

First update the service communication certificate for the ADFS running the following command and verify:

Set-AdfsCertificate -CertificateType Service-Communications -Thumbprint 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
Get-AdfsCertificate


Then restart the ADFS service:

Restart-Service ADFSSRV


Then update the new SSL cert bindings to ADFS configuration and verify:

Set-AdfsSslCertificate -Thumbprint 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
Get-AdfsSslCertificate


Again; restart the ADFS service (just to be sure)

Restart-Service ADFSSRV


Check if the certificates are in place and properly bounded:
 

PS H:\> netsh http show sslcert

SSL Certificate bindings:
-------------------------

    Hostname:port                : sts.domain.com:443
    Certificate Hash             : 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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               : AdfsTrustedDevices
    DS Mapper Usage              : Disabled
    Negotiate Client Certificate : Disabled

    Hostname:port                : localhost:443
    Certificate Hash             : 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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               : AdfsTrustedDevices
    DS Mapper Usage              : Disabled
    Negotiate Client Certificate : Disabled

    Hostname:port                : sts.domain.com:49443
    Certificate Hash             : 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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 : Enabled


PS H:\>

 

Watchout for the default binding!

I experienced out of first hand, that it is possible that the new certificate is not bound on the HTTP.sys level after updating the certificate within ADFS.

This is mostly the case when you're working with a OSI Layer 7 Load balancer for example a Citrix NetScaler. Citrix doesn't support SNI binding to its back-end connections, only to its front-end facing connections; this was the case prior NS 11.1 build 54.
Since the release of NS 11.1 build 54, Citrix NetScaler supports SNI binding to its back-end connections, but i must make a annotation to this.

Citrix published this new feature in it's relase notes, but didn't mention this is only possible if you are NOT working with servicegroups or SSL profiles.

So check if the Certificate Hash is correct on the 0.0.0.0:443 or localhost:443; if not the case, use the following commands.

The AppID is the same for every ADFS server/instance for every ADFS server; you will notice that the AppID issued in my command is exactly the same as yours.

netsh http delete sslcert ipport=0.0.0.0:443
netsh http add sslcert ipport=0.0.0.0:443 certhash=<YOUR_NEW_THUMBPRINT> appid={5d89a20c-beab-4389-9447-324788eb944a} certstorename=MY sslctlstorename=AdfsTrustedDevices


or
 

netsh http delete sslcert ipport=localhost:443
netsh http add sslcert ipport=localhost:443 certhash=<YOUR_NEW_THUMBPRINT> appid={5d89a20c-beab-4389-9447-324788eb944a} certstorename=MY sslctlstorename=AdfsTrustedDevices



Notice: do this on every ADFS server in your farm (and yes; life is a b*tch) wink

When done; grab yourself a fresh cup coffee
Afterwards; go the next chapter.

 

Replacing the certificates on the WAP servers.

Go to the ADFS Proxy servers (WAP).

Do the same on your WAP server, concerning the import certificates.
Then issue the following commands:
 

Get-WebApplicationProxySslCertificate





Then do:
 

Set-WebApplicationProxySslCertificate -Thumbprint 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904

 



Check the result:




Double check the port bindings are correct; the Certificate Hash must be the same as your new thumbprint
 

PS C:\Users\Administrator> netsh http show sslcert

SSL Certificate bindings:
-------------------------

    Hostname:port                : sts.domain.com:443
    Certificate Hash             : 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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               : AdfsTrustedDevices
    DS Mapper Usage              : Disabled
    Negotiate Client Certificate : Disabled

    Hostname:port                : sts.domain.com:49443
    Certificate Hash             : 100XXXXXXXMY_NEW_THUMBPRINTXXXXXXXXXX904
    Application ID               : {5d89a20c-beab-4389-9447-324788eb944a}
    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 : Enabled

Incase you see a default binding (probably the case if you are using an mature load balancer), you must also replace it there.

The AppID is the same for every ADFS server/instance for every ADFS server; you will notice that the AppID issued in my command is exactly the same as yours.

netsh http delete sslcert ipport=0.0.0.0:443
netsh http add sslcert ipport=0.0.0.0:443 certhash=<YOUR_NEW_THUMBPRINT> appid=100ad0af0b9505bdd4bac9d23de187255082a904 certstorename=MY

And finally; restart the ADFS service

Restart-Service ADFSSRV


 

So, how do I test the functionality of the ADFS?


The ADFS uses the IIS to host his own end points. There is also a simple Login-page that every user can use:
 

'https://sts.domain.com_or_other_FQDN/adfs/ls/IdpInitiatedSignon.aspx'


Afterwards a simple „Login-Page“ appears – after one click on „login“ you should see something 'you are signed in'

That's it! were done here. Thank you for reading!