IIS Crypto Explained

NOTE – This post is outdated. For a full list of registry keys, see our updated FAQ.

Lately, we have been receiving a lot of questions with regards to what exactly IIS Crypto does. I will do my best to answer these questions in this post.

IIS Crypto was created to simplify enabling and disabling various protocols and cipher suites on the many servers we administer. Originally we had a script that we would execute on each server after the initial setup, however, some servers needed different protocols and cipher suites enabled. We also wanted to see the current configuration of existing servers. Thus IIS Crypto was born.

IIS Crypto simply sets a few registry keys to enable/disable protocols, ciphers and hashes as well as reorder cipher suites. Microsoft has an article explaining all of the settings here. These are the exact keys IIS Crypto uses:

HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsMulti-Protocol Unified HelloServer
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsPCT 1.0Server
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsSSL 2.0Server
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsSSL 3.0Server
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.0Server
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.1Server
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELProtocolsTLS 1.2Server

HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersNULL
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersDES 56/56
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC2 40/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC2 56/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC2 128/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC4 40/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC4 56/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC4 64/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersRC4 128/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersTriple DES 168/168
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersAES 128/128
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELCiphersAES 256/256

HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELHashesMD5
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELHashesSHA

HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELKeyExchangeAlgorithmsDiffie-Hellman
HKLMSYSTEMCurrentControlSetControlSecurityProvidersSCHANNELKeyExchangeAlgorithmsPKCS

Each registry key has an “Enabled” value that is set. The protocols have an additional value named “DisabledByDefault” that is also set.

To reorder the cipher suites, IIS Crypto uses the following keys:

HKLMSYSTEMCurrentControlSetControlCryptographyConfigurationLocalSSL0010002

HKLMSOFTWAREPoliciesMicrosoftCryptographyConfigurationSSL0010002

The first registry key contains the list of supported cipher suites on the server. The second registry key is used to set the cipher suites order. These are the same keys that the group policy editor (gpedit.msc) use. Microsoft explains how to do this manually here. The full list of cipher suites supported is here.

IIS Crypto also supports pre-defined templates that can be set with a single button click:

PCI – Disables everything except SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2, RC4 128, Triple DES 168, AES 128, AES 256, MD5, SHA1, DH and PKCS.

FIPS 140-2 – Disables everything except TLS 1.0, TLS 1.1, TLS 1.2, Triple DES 168, AES 128, AES 256, SHA1, DH and PKCS.

BEAST – The same as PCI, but also reorders the cipher suite as follows:

TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P384
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA

Feel free to leave a comment if you have any questions.

19 thoughts on “IIS Crypto Explained

  1. Counter intuitive perhaps, but solved the issue by deleting the SCHANNEL tree in the registry (after exporting first for safety) and then IISCrypto 2.0 opens successfully. Seems it was trying to get a value it disagreed with. A bug for Nartac to fix, but deleting the tree works:

    HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL

    Like

    1. Hi,

      Little question on the reordering with BEAST: why do you put RC4 as the preferred?

      Would it not be better to have first TLS v1.2 only ciphers (like AES/GCM), then RC4 and then the BEAST vulnerable ciphers from TLS 1.0 and SSL 3.0?

      This way, you do not have CBC at first (so the PCI scans should be OK), remain protected against BEAST, promote TLS v1.2 and stay compatible with the old browsers.

      Like

    2. Hi,

      So after some digging, the missing 3DES does seem to be an issue in the latest build. I'll post a new build later this week after we test it with all of the various scans. Thanks again!

      – Jeff

      Like

    3. Great tool! although I am confused as to why there is a PCI and a BEAST option?

      I found that when applying the PCI configuration, my PCI ASV scan still flags up with BEAST due to the cipher ordering.

      Therefore should the BEAST option not be renamed PCI and the current PCI option removed as it does not achieve compliance?

      Alex

      Like

    4. @John

      On the Windows Server 2008 R2 x64 machine I just tested (using ssl-cipher-suite-enum connecting to IIS7.5), setting 'DisabledByDefault' to 0 is required to enable TLS1.1 and TLS1.2.

      Thanks to all those who have worked on this awesome tool!

      Like

    5. This Tool was great once, but doesn't seem to be compliant tp PCI-DSS 3.1. After using the PCI Button on a Domain Controller, Rapid7 Scans still show failures regarding CBC Ciphers and DES/IDEA Ciphers.

      Any chance of an upgrade soon?

      Like

    6. Hi,

      When using version 2.0 Build 11 on Windows Server 2008r2 it adds or modifies the following registry key:
      "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168"

      Should this key be "Triple DES 168" or "Triple DES 168/168"? Should IISCrypto adapt depending on the OS?
      https://social.technet.microsoft.com/Forums/lync/en-US/7a143f27-da47-4d3c-9eb2-6736f8896129/disabling-3des-breaks-rdp-to-server-2008-r2?forum=winRDc

      Regards
      Neil

      Like

    7. We had to configure .NET to use stronger protocols before disabling TLS 1.0 to avoid System.InvalidOperationException in IIS.

      REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727" /v SchUseStrongCrypto /t REG_DWORD /d 1 /f
      REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" /v SchUseStrongCrypto /t REG_DWORD /d 1 /f
      REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727" /v SchUseStrongCrypto /t REG_DWORD /d 1 /f
      REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" /v SchUseStrongCrypto /t REG_DWORD /d 1 /f

      Like

    8. This is a fantastic tool for implementing the most current Best Practices for securing IIS. I have successfully deployed these settings to one of our public domain QA servers used by out customers for QA Testing, but it seems to only allow TLS 1.0 for any non-public (self-signed certificate) server that we use for internal testing (DEV, UAT). No matter what I do, my IE 11 browser that I set to allow TLS 1.0, TLS 1.1, TLS 1.2 will always stepdown to the TLS 1.0 protocol. I have used IISCrypto to set each of these servers to Best Practices settings. All of these Windows Servers are running WS 2008 R2 (please do not ridicule me – it is not my doing). Is there something else I need to do. Does this have anything to do with self-signed certs? That is the only common denominator (that I can identify) that is different between the public domain server with an Entrust cert and the internal servers with hostnames and self-signed certs. The registry entries that you have indicated above are identical on all servers after setting them with BP settings of IISCrypto.

      BTW- thanks so much for your free tool – are you taking donations to support this software?

      Like

    9. Application: IISCrypto.exe
      Framework Version: v4.0.30319
      Description: The process was terminated due to an unhandled exception.
      Exception Info: System.InvalidCastException
      at IISCrypto.Common.Manager.GetRegistryValue[[System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](IISCrypto.Common.Models.RegistryItemModel)
      at IISCrypto.Common.Manager.LoadSchannelItemsFromRegistry(IISCrypto.Common.Models.RegistryItemModel[], System.Collections.Generic.List`1<IISCrypto.Common.Models.CipherItemModel>)
      at IISCrypto.Common.Manager.LoadCurrentTemplateFromOS()
      at IISCrypto.Common.Manager..ctor()
      at IISCrypto.Main.MainForm..ctor()
      at IISCrypto.Main.Program.Main()

      Like

    10. I am also getting the InvalidCastException preventing me from running IIS Crypto on my Windows 2016 server. Exact same issue as Manjoor & Richard above are reporting.

      Like

    11. Exact same issue here. Tried both 2012 R2 and 2016:

      Application: IISCrypto.exe
      Framework Version: v4.0.30319
      Description: The process was terminated due to an unhandled exception.
      Exception Info: System.InvalidCastException
      at IISCrypto.Common.Manager.GetRegistryValue[[System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](IISCrypto.Common.Models.RegistryItemModel)
      at IISCrypto.Common.Manager.LoadSchannelItemsFromRegistry(IISCrypto.Common.Models.RegistryItemModel[], System.Collections.Generic.List`1<IISCrypto.Common.Models.CipherItemModel>)
      at IISCrypto.Common.Manager.LoadCurrentTemplateFromOS()
      at IISCrypto.Common.Manager..ctor()
      at IISCrypto.Main.MainForm..ctor()
      at IISCrypto.Main.Program.Main()

      Like

    12. Same error on Windows Server 2012 R2 (latest version on Azure) with .NET 4.5 using GUI tool
      When using CLI (IISCryptoCli.exe) get:
      Error: Specified cast is not valid.

      Tried John Zeepvat recommendation of deleting the SCHANNEL tree in the registry (after exporting first for safety) and then IISCrypto 2.0 opens successfully and CLI runs too.

      Took one level further by trying child objects and when only the two following were deleted it also opens successfully.
      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
      HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
      So must lie within these. Export of these as is on new vanilla Windows Server 2012 R2 (latest version on Azure) below:
      ====
      Windows Registry Editor Version 5.00

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols]

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0]

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
      "DisabledByDefault"=dword:00000001

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0]

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client]
      "Enabled"="0"

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
      "Enabled"="0"
      ====

      ====
      Windows Registry Editor Version 5.00

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers]

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128]
      "Enabled"="0"

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128]
      "Enabled"="0"

      [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128]
      "Enabled"="0"
      ====

      Like

    13. Same error as John Zeepvat on a new Azure Windows 2016 VM. Turns out, the "Enabled" values in the Ciphers and Protocols keys are in the registry as strings "REG_SZ" whereas IISCrypto is expecting them to be numeric "REG_DWORD". These values must have been added by default in the Windows server images. I'm glad to have found your solution, because I really appreciate using IISCrypto to set the TLS settings so quickly. So you can (after exporting a backup of the SCHANNEL tree) just remove the "Enabled" values or convert them to REG_DWORD values and then launch IISCrypto.

      Like

    14. Had exactly the same problem as above, deleting those enabled values resolved the issue and IISCyrpto works as expected now.

      Highlights that we probably need a support forum or something from Nartac.

      Like

Comments are closed.