Public/Disable-CipherProtocol.ps1
|
function Disable-CipherProtocol { <# .SYNOPSIS Hardens the SCHANNEL configuration by disabling weak protocols and cipher suites. .DESCRIPTION Configures SCHANNEL registry keys to enable TLS 1.2 and disable TLS 1.1, TLS 1.0, SSL 3.0, and SSL 2.0 for both Server and Client roles. Also enforces strong crypto for .NET Framework applications and disables 24 known-weak TLS cipher suites. A system restart is required for changes to take effect. .INPUTS None. Parameters must be supplied directly. .OUTPUTS None. .PARAMETER ComputerName The target computer. Defaults to the local machine. .PARAMETER Force Restarts the computer immediately after applying changes. .EXAMPLE Disable-CipherProtocol Applies SCHANNEL hardening on the local machine and warns that a restart is needed. .EXAMPLE Disable-CipherProtocol -ComputerName 'Server01' -Force Applies SCHANNEL hardening on Server01 and restarts it immediately. .NOTES Requires Administrator privileges. Disabling TLS 1.0/1.1 may break legacy applications that do not support TLS 1.2. Test in a non-production environment before broad deployment. Remote operations require WinRM to be configured on the target machine. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] [OutputType([void])] param ( [Parameter(Mandatory = $false)] [string]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [switch]$Force ) $isLocal = ($ComputerName -ieq $env:COMPUTERNAME) -or ($ComputerName -ieq 'localhost') -or ($ComputerName -eq '127.0.0.1') if ($PSCmdlet.ShouldProcess($ComputerName, 'Enable TLS 1.2; disable TLS 1.1, TLS 1.0, SSL 3.0, SSL 2.0; disable 24 weak cipher suites')) { $work = { $schannelBase = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols' function Set-ProtocolState { param([string]$Protocol, [int]$Enabled) $disabled = if ($Enabled -eq 1) { 0 } else { 1 } foreach ($role in 'Server', 'Client') { $path = "$schannelBase\$Protocol\$role" New-Item -Path $path -Force | Out-Null Set-ItemProperty -Path $path -Name 'Enabled' -Value $Enabled -Type DWord Set-ItemProperty -Path $path -Name 'DisabledByDefault' -Value $disabled -Type DWord } } Set-ProtocolState -Protocol 'TLS 1.2' -Enabled 1 Write-Verbose 'TLS 1.2: enabled.' Set-ProtocolState -Protocol 'TLS 1.1' -Enabled 0 Write-Verbose 'TLS 1.1: disabled.' Set-ProtocolState -Protocol 'TLS 1.0' -Enabled 0 Write-Verbose 'TLS 1.0: disabled.' Set-ProtocolState -Protocol 'SSL 3.0' -Enabled 0 Write-Verbose 'SSL 3.0: disabled.' Set-ProtocolState -Protocol 'SSL 2.0' -Enabled 0 Write-Verbose 'SSL 2.0: disabled.' # Enforce strong crypto for .NET Framework applications $dotNetPaths = @( (Get-ChildItem 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.*' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty PSPath), (Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.*' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty PSPath) ) | ForEach-Object { $_ } foreach ($path in $dotNetPaths) { Set-ItemProperty -Path $path -Name 'SystemDefaultTlsVersions' -Value 1 -Type DWord -ErrorAction SilentlyContinue Set-ItemProperty -Path $path -Name 'SchUseStrongCrypto' -Value 1 -Type DWord -ErrorAction SilentlyContinue } Write-Verbose '.NET Framework strong crypto enforced.' $weakCiphers = @( 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_DHE_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', 'TLS_RSA_WITH_3DES_EDE_CBC_SHA', 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256', 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256', 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA', 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA', 'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA', 'TLS_RSA_WITH_RC4_128_SHA', 'TLS_RSA_WITH_RC4_128_MD5', 'TLS_RSA_WITH_NULL_SHA256', 'TLS_RSA_WITH_NULL_SHA', 'TLS_PSK_WITH_AES_256_GCM_SHA384', 'TLS_PSK_WITH_AES_128_GCM_SHA256', 'TLS_PSK_WITH_AES_256_CBC_SHA384', 'TLS_PSK_WITH_AES_128_CBC_SHA256', 'TLS_PSK_WITH_NULL_SHA384', 'TLS_PSK_WITH_NULL_SHA256' ) foreach ($cipher in $weakCiphers) { try { Disable-TlsCipherSuite -Name $cipher -ErrorAction Stop Write-Verbose "Disabled cipher suite: $cipher" } catch { if ($_.Exception.HResult -eq -1073741275) { Write-Verbose "Already disabled: $cipher" } else { Write-Warning "Failed to disable cipher suite '$cipher': $($_.Exception.Message)" } } } } if ($isLocal) { & $work } else { Invoke-Command -ComputerName $ComputerName -ScriptBlock $work } Write-Verbose "SCHANNEL hardening applied on '$ComputerName'." Write-Warning "A system restart is required for changes to take effect." if ($Force -and $PSCmdlet.ShouldProcess($ComputerName, 'Restart computer to apply changes')) { Restart-Computer -ComputerName $ComputerName -Force } } } |