-
-
Save SidShetye/29d6d48dfa0c2f5488a4 to your computer and use it in GitHub Desktop.
# 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 | |
} |
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
Does this will also disable 3DES cipher suites? It was not clear from the code
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.
Looks great, thanks. Filename differs from the one in comment on line 2.