Skip to content

Instantly share code, notes, and snippets.

@SidShetye
Last active August 14, 2023 14:59
Show Gist options
  • Save SidShetye/29d6d48dfa0c2f5488a4 to your computer and use it in GitHub Desktop.
Save SidShetye/29d6d48dfa0c2f5488a4 to your computer and use it in GitHub Desktop.
Script to harden SSL/TLS on Azure Cloud Service
# Call this from inside a startup task/batch file as shown in the next two lines (minus the '# ')
# PowerShell -ExecutionPolicy Unrestricted .\HardenSsl.ps1 >> log-HardenSsl.txt 2>&1
# EXIT /B 0
# Credits:
# http://azure.microsoft.com/blog/2014/10/19/how-to-disable-ssl-3-0-in-azure-websites-roles-and-virtual-machines/
# http://lukieb.blogspot.com/2014/11/tightening-up-your-azure-cloud-service.html
$nl = [Environment]::NewLine
$regkeys = @(
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client",
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server",
"HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
)
######################################################################################
# CIPHER SUITE CONFIGURATION
#
# Redone in 2015 per http://security.stackexchange.com/questions/76993/now-that-it-is-2015-what-ssl-tls-cipher-suites-should-be-used-in-a-high-securit
# Plus
# + added P521 for certain ECDHE + AES256 modes
# + need to add _P256 etc at the end of TLS_ECDHE_*** ciphersuites for Windows/SCHANNEL format
$cipherorder ="" +
# TLS 1.2 AEAD only (all are SHA-2 as well)
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384_P521," +
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384_P384," +
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384_P256," +
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256_P384," + # this is a TLS 1.2 "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-3
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256_P256," + # this is a TLS 1.2 "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-3
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384," +
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," +
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P521," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P256," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P384," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
# TLS 1.2 SHA2 family
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," +
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," +
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521," +
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384," +
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256," +
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384," + # this is a TLS 1.2 "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-3
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256," + # this is a TLS 1.2 "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-3
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384," + # this is a TLS 1.2 "may" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P256," + # this is a TLS 1.2 "may" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P384," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256," + # this is a TLS 1.2 "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-5
# TLS 1.0 and 1.1 with modern ciphers (and outdated hashes, since that's all that's available)
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P521," + # this is a "may" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384," + # this is a "may" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256," + # this is a "may" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P384," + # this is a "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256," + # this is a "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA," +
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA," +
# TLS 1.0 and 1.1 with older but still reasonable ciphers and outdated hashes
# IE 8 on Windows XP is still out of luck, as is Java 6u45 due to DH parameter maximums.
"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," +
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA_P384," + # this is a "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA_P256," + # this is a "should" category cipher suite for servers using RSA private keys and RSA certificates per NIST SP800-52 revision 1 table 3-2
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA_P384," + # this is a "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-4
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA_P256," + # this is a "should" category cipher suite for servers using elliptic curve private keys and ECDSA certificates per NIST SP800-52 revision 1 table 3-4
# For compatibility
"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"
######################################################################################
# If any settings are changed, this will change to $True and the server will reboot
$reboot = $False
Function Set-CryptoSetting {
param (
$keyindex,
$value,
$valuedata,
$valuetype,
$restart
)
# For printing to console
$regKey = $regkeys[$keyindex]
# Check for existence of registry key, and create if it does not exist
If (!(Test-Path -Path $regKey)) {
Write-Host "Creating key: $regKey$nl"
New-Item $regKey | Out-Null
}
If($value -eq $null){
return $restart
}
# Get data of registry value, or null if it does not exist
$val = (Get-ItemProperty -Path $regKey -Name $value -ErrorAction SilentlyContinue).$value
If ($val -eq $null) {
# Value does not exist - create and set to desired value
Write-Host "Value $regKey\$value does not exist, creating...$nl"
New-ItemProperty -Path $regKey -Name $value -Value $valuedata -PropertyType $valuetype | Out-Null
$restart = $True
} Else {
# Value does exist - if not equal to desired value, change it
If ($val -ne $valuedata) {
Write-Host "Value $regKey\$value not correct, setting it$nl"
Set-ItemProperty -Path $regKey -Name $value -Value $valuedata
$restart = $True
}
Else
{
Write-Host "Value $regKey\$value already set correctly$nl"
}
}
return $restart
}
# Special function that can handle keys that have a forward slash in them. Powershell changes the forward slash
# to a backslash in any function that takes a path.
Function Set-CryptoKey {
param (
$parent,
$childkey,
$value,
$valuedata,
$valuetype,
$restart
)
$child = $parent.OpenSubKey($childkey, $true);
If ($child -eq $null) {
# Need to create child key
$child = $parent.CreateSubKey($childkey);
}
# Get data of registry value, or null if it does not exist
$val = $child.GetValue($value);
If ($val -eq $null) {
# Value does not exist - create and set to desired value
Write-Host "Value $child\$value does not exist, creating...$nl"
$child.SetValue($value, $valuedata, $valuetype);
$restart = $True
} Else {
# Value does exist - if not equal to desired value, change it
If ($val -ne $valuedata) {
Write-Host "Value $child\$value not correct, setting it$nl"
$child.SetValue($value, $valuedata, $valuetype);
$restart = $True
}
Else
{
Write-Host "Value $child\$value already set correctly$nl"
}
}
return $restart
}
# Ensure TLS 1.2 parent folder exists
$reboot = Set-CryptoSetting 6 $null $null $null $reboot
# Ensure TLS 1.2 enabled for client
$reboot = Set-CryptoSetting 7 DisabledByDefault 0 DWord $reboot
$reboot = Set-CryptoSetting 7 Enabled 1 DWord $reboot
# Ensure TLS 1.2 enabled for server
$reboot = Set-CryptoSetting 8 Enabled 1 DWord $reboot
$reboot = Set-CryptoSetting 8 DisabledByDefault 0 DWord $reboot
# Ensure SSL 2.0 parent folder exists
$reboot = Set-CryptoSetting 9 $null $null $null $reboot
# Ensure SSL 2.0 disabled for client
$reboot = Set-CryptoSetting 10 DisabledByDefault 1 DWord $reboot
# Ensure SSL 2.0 disabled for server
$reboot = Set-CryptoSetting 11 Enabled 0 DWord $reboot
# Ensure SSL 3.0 parent folder exists
$reboot = Set-CryptoSetting 12 $null $null $null $reboot
# Ensure SSL 3.0 disabled for client
$reboot = Set-CryptoSetting 13 DisabledByDefault 1 DWord $reboot
# Ensure SSL 3.0 disabled for server
$reboot = Set-CryptoSetting 14 Enabled 0 DWord $reboot
# Set cipher priority
$reboot = Set-CryptoSetting 15 Functions $cipherorder String $reboot
# We have to do something special with these keys if they contain a forward-slash since
# Powershell converts the forward slash to a backslash and it screws up the creation of the key!
#
# Just create these parent level keys first
$cipherskey = (get-item HKLM:\).OpenSubKey("SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers",$true)
If ($cipherskey -eq $null) {
$cipherskey = (get-item HKLM:\).CreateSubKey("SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers")
}
$hasheskey = (get-item HKLM:\).OpenSubKey("SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes",$true)
If ($hasheskey -eq $null) {
$hasheskey = (get-item HKLM:\).CreateSubKey("SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes")
}
# Then add sub keys using a different function
# Disable RC4, DES, EXPORT, eNULL, aNULL, PSK and aECDH
# Details at https://support.microsoft.com/en-us/kb/245030
$reboot = Set-CryptoKey $cipherskey "RC4 128/128" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "Triple DES 168" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "RC2 128/128" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "RC4 64/128" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "RC4 56/128" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "RC2 56/128" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "DES 56" Enabled 0 DWord $reboot # It's not clear whether the key is DES 56 or DES 56/56
$reboot = Set-CryptoKey $cipherskey "DES 56/56" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "RC4 40/128" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $cipherskey "RC2 40/128" Enabled 0 DWord $reboot
# Disable MD5, enable SHA (which should be by default)
$reboot = Set-CryptoKey $hasheskey "MD5" Enabled 0 DWord $reboot
$reboot = Set-CryptoKey $hasheskey "SHA" Enabled 0xFFFFFFFF DWord $reboot
$cipherskey.Close();
$hasheskey.Close();
# If any settings were changed, reboot
If ($reboot) {
Write-Host "Rebooting now..."
# shutdown: restart, in 5 sec, human readable reason/comment, force (running apps to close),
# machine readable reason (planned, 2:4 as reason)
shutdown.exe /r /t 5 /c "Crypto settings changed" /f /d p:2:4
}
@rjk
Copy link

rjk commented Jun 28, 2015

Looks great, thanks. Filename differs from the one in comment on line 2.

@clausndk
Copy link

I updated the script's cipherorder to:

$cipherorder = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P521,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P521,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P521,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P521,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P384,"
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P521,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P521,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P384,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P521,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P521,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P384,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P521,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P384,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P521,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P384,"
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256,"
$cipherorder += "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,"
$cipherorder += "TLS_DHE_DSS_WITH_AES_256_CBC_SHA,"
$cipherorder += "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,"
$cipherorder += "TLS_DHE_DSS_WITH_AES_128_CBC_SHA,"
$cipherorder += "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,"
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256,"
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA,"
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256,"
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA,"
$cipherorder += "TLS_RSA_WITH_RC4_128_SHA,"
$cipherorder += "TLS_RSA_WITH_3DES_EDE_CBC_SHA"

To better support Forward Secrecy:
https://www.hass.de/content/setup-your-iis-ssl-perfect-forward-secrecy-and-tls-12

@omerlh
Copy link

omerlh commented Aug 22, 2017

Does this will also disable 3DES cipher suites? It was not clear from the code

@superphonic
Copy link

For me using a Server 2008 R2 web role, line 26 needed to be

"HKLM:\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\SSL\0010002"

to change the cipher order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment