如何在 Windows Server 2019 上的 ASP.NET MVC 应用程序 运行 中启用 TLS 1.0 和 TLS 1.1?

How do I enable TLS 1.0 and TLS 1.1 in ASP.NET MVC application running on Windows Server 2019?

我有一个 ASP.NET MVC Web 服务托管在 Microsoft Azure 云服务中(作为 Web 角色),当前针对 .NET Framework 4.5.2 并配置为 运行 on Windows Server 2012。我需要将它迁移到 .NET Framework 4.7.2 和 Windows Server 2019。一切正常,除了...

Windows Server 2012 的配置使得 IIS 默认允许 TLS 1.0、TLS 1.1 和 TLS 1.2,但 Windows Server 2019 的 IIS 配置为仅允许 TLS 1.2 这可能会破坏某些客户端,所以我想在 Windows 2019 年暂时启用 TLS 1.0 和 1.1,然后与客户端交谈并禁用除 TLS 1.2

之外的所有功能

我发现 this answer 这表明我更改了注册表项

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]

并放

"Enabled"=dword:ffffffff
"DisabledByDefault"=dword:00000000

在那里。 (我也尝试 dword:00000001 而不是 dword:ffffffff - 没有区别)我将其作为启动任务包含在内,以便将必要的更改导入注册表。

没用。我使用 https://www.ssllabs.com/ssltest 检查可用的 TLS 模式。它说在更改前后都只允许使用 TLS 1.2。它正确地显示了 1.0、1.1 和 1.2 可用于 Windows Server 2012。

如何启用 TLS 1.0 和 1.1?

您可以使用以下 Powershell 脚本启用 tls 1.0 和 1.1:

    [CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[ValidateSet("SSL30","TLS10","TLS11","TLS12")]
[string]$Proto,
[ValidateSet("Client","Server")]
[string]$Target,
[Parameter(Mandatory=$True)]
[ValidateSet("Enable","Disable")]
$Action)

Function CheckKey{
param(
[string]$Proto
)
$RegKey = $null

switch ($Proto){
   SSL30 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0"}
   TLS10 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0"}
   TLS11 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1"}
   TLS12 {$RegKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2"}
   default{"Not supported protocol. Possible values: SSL30, TLS10, TLS11, TLS12"
            exit}
  }
return $Regkey
}

$RegKey = CheckKey -Proto $Proto
[string[]]$TargetKey = $null
if(!($Target)){
  Write-Host "Setting up both Client and Server protocols"
  $TargetKey = $(Join-Path $RegKey "Client").ToString()
  $TargetKey += $(Join-Path $RegKey "Server").ToString()
  if(!(Test-path -Path $TargetKey[0])){
       New-Item $TargetKey[0] -Force
   }
  if(!(Test-path -Path $TargetKey[1])){
       New-Item $TargetKey[1] -Force
    }
  } 
else{
  Write-Host "Setting up $Target protocols"
  $TargetKey = $(Join-Path $RegKey $Target).ToString()
  if(!(Test-path -Path $(Join-Path $RegKey $Target))){
       New-Item $TargetKey -Force   
    }
 }

Function SetProto{
param(

[string[]]$TargetKey,
[string]$Action
)

foreach($key in  $TargetKey){
   try{
       Get-ItemProperty -Path $key -Name "Enabled" -ErrorAction Stop | Out-Null
       if($Action -eq "Disable"){
          Write-Host "`t`Updating $key"                     
          Set-ItemProperty -Path $key -Name "Enabled" -Value 0 -Type "DWord"
         }
       else{
          Write-Host "`t`Updating $key"
          Set-ItemProperty -Path $key -Name "Enabled" -Value 1 -Type "DWord"
         }
      }Catch [System.Management.Automation.PSArgumentException]{
          if($Action -eq "Disable"){
             Write-Host "`t`Creating $key"
             New-ItemProperty -Path $key -Name "Enabled" -Value 0 -PropertyType "DWord"
            }
          else{
             Write-Host "`t`Creating $key"
             New-ItemProperty -Path $key -Name "Enabled" -Value 1 -PropertyType "DWord"
           }
       }

try{
     Get-ItemProperty -Path $key -Name "DisabledByDefault" -ErrorAction Stop | Out-Null
     if($Action -eq "Disable"){
        Write-Host "`t`Updating $key"
        Set-ItemProperty -Path $key -Name "DisabledByDefault" -Value 1 -Type "DWord"
       }
     else{
        Write-Host "`t`Updating $key"
        Set-ItemProperty -Path $key -Name "DisabledByDefault" -Value 0 -Type "DWord"
        }
     }Catch [System.Management.Automation.PSArgumentException]{
        if($Action -eq "Disable"){
           Write-Host "`t`Creating $key"
           New-ItemProperty -Path $key -Name "DisabledByDefault" -Value 1 -PropertyType "DWord"
          }
        else{
           Write-Host "`t`Creating $key"
           New-ItemProperty -Path $key -Name "DisabledByDefault" -Value 0 -PropertyType "DWord"
          }
     }
  }
}

SetProto -TargetKey $TargetKey -Action $Action

Write-Host "The operation completed successfully, reboot is required" -ForegroundColor Green

使用网络监控工具检查正在使用哪个协议站点。 Microsoft Network Monitor

启用或禁用协议后不要忘记重启机器。

为 TLS 1.0/1.1 添加密码套件。完整脚本(运行 作为管理员):

$suites = @(
    'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256',
    'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',
    'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'  ,
    'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'  ,
    'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256',
    'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384',
    'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256'  ,
    'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384'  ,

    'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA'   ,
    'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA'   ,
    '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'           
)

$registry = @(
    @{Path='HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server';Name='DisabledByDefault';Type='DWord';Value=0},
    @{Path='HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server';Name='Enabled';Type='DWord';Value=1},
    @{Path='HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server';Name='DisabledByDefault';Type='DWord';Value=0},
    @{Path='HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server';Name='Enabled';Type='DWord';Value=1},
    @{Path='HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL[=10=]010002';Name='Functions';Type='String';Value=$suites -Join ','}
)

$reboot = $null
foreach ($row in $registry) {
    if (-Not(Test-Path $row.Path)) {
        New-Item -Path $row.Path -Force | Out-Null
    }

    try {
        $val = Get-ItemPropertyValue -Path $row.Path -Name $row.Name
    } catch {
        $val = $null
    }

    if ($val -ne $row.Value) {
        $reboot = $true
        Set-ItemProperty -Path $row.Path -Name $row.Name -Type $row.Type -Value $row.Value -Force
        Write-Host "$($row.Path)!$($row.Name)=$($row.Value)"
    }
}

if ($reboot -eq $true) {
    Write-Host "Rebooting now..."
    shutdown.exe /r /t 0 /c "Rebooting for registry changes to take effect" /f /d p:2:4
}