Monday, February 22, 2021

Dealing with TLS Cipher suites in HTTPS calls on cloud hosted environments (CHE)

Another fine day at the office gave me a challenge that I met before but never really investigated. It has to do with HTTPS calls that fails due to difference between supported TLS cipher suites on server that host a web service and the client consuming it.

I always though that if I ask the client to make a TLS 1.2 call and the server supports TLS 1.2 then everything should be in order. But that is not necessarily correct because of the Cipher suites that each end supports.

An explanation of ciphers is here https://blog.keyfactor.com/cipher-suites-explained if you are into that kind of stuff.

My assignment was to make a call to a semi-public webservice (just need a API-key) from D365 FO but as usually I did a few tests from Postman and C# from my own PC before hitting the D365 FO CHE.

In Postman I immediately got a valid response so I went to my trusted VS 2019 IDE and wrote this test program and again I got the expected answer:

 

However, when I moved the test program to my CHE and ran it, I got the error message:

“The request was aborted: Could not create SSL/TLS secure channel”


I used the Qualys SSL Labs (https://www.ssllabs.com/ssltest/analyze.html) tool to check that the service actually supported TLS 1.2 and it did.


I fired up Fiddler Everywhere (https://www.telerik.com/download/fiddler/fiddler-everywhere-windows) and found that even though the request was made with TLS 1.2 there was no overlapping supported ciphers.

My CHE client did not have any TLS_ECDHE_ECDSA_* ciphers which was all the service supported.


So, I checked that the Window server 2016 supported the needed cipher through this link: https://docs.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel

And that D365 FO apps also supported the right ciphers through this link: https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/sysadmin/encryption

 

Everything seems to be alright and supported, but still the call would only used unsupported ciphers.

Both Windows server 2016 and D365 FO supported these 4 ciphers, but the client did not:

  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)                                         
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)                                       
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)                                         
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)                                       

At last, I got a hint from Microsoft support that I should check the registry: HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002\ and there I found that only part of the server supported ciphers was listed.

I added the 4 ciphers above like this:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002]

"Functions"="TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA"

That made a difference, and everything worked.

 

1 comment:

  1. A simpler way is to utilize PowerShell to add these:

    Enable-TlsCipherSuite -Name "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"

    You could do an array like:
    $objs = @("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256")
    $objs | ForEach-Object { Enable-TlsCipherSuite -Name $_}

    ReplyDelete