Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
客户端和服务器无法通信,因为它们没有通用的算法-ASP.NET C#IIS TLS 1.0/1.1/1.2-Win32Exception_C#_Asp.net_Ssl_Iis 7.5_Poodle Attack - Fatal编程技术网

客户端和服务器无法通信,因为它们没有通用的算法-ASP.NET C#IIS TLS 1.0/1.1/1.2-Win32Exception

客户端和服务器无法通信,因为它们没有通用的算法-ASP.NET C#IIS TLS 1.0/1.1/1.2-Win32Exception,c#,asp.net,ssl,iis-7.5,poodle-attack,C#,Asp.net,Ssl,Iis 7.5,Poodle Attack,我对C#PayTrace网关有问题。下面的代码一直工作正常,直到昨天,我相信他们关闭了SSL3,因为狮子狗攻击。当运行下面的代码时,我们得到以下消息。远程服务器已强制关闭连接。在对这个问题进行了一些研究之后,我们确定,由于我们的IIS服务器7.5被配置为仍然使用SSL3,C#默认为SSL3,PayTrace将强制关闭连接。然后,我们从服务器上删除了SSL3。这将导致以下错误: 客户端和服务器无法通信,因为它们没有共同的算法。 我的猜测是,现在SSL 3被删除了,我们需要在服务器上安装额外的SSL

我对C#PayTrace网关有问题。下面的代码一直工作正常,直到昨天,我相信他们关闭了SSL3,因为狮子狗攻击。当运行下面的代码时,我们得到以下消息。远程服务器已强制关闭连接。在对这个问题进行了一些研究之后,我们确定,由于我们的IIS服务器7.5被配置为仍然使用SSL3,C#默认为SSL3,PayTrace将强制关闭连接。然后,我们从服务器上删除了SSL3。这将导致以下错误:

客户端和服务器无法通信,因为它们没有共同的算法。

我的猜测是,现在SSL 3被删除了,我们需要在服务器上安装额外的SSL算法。我们的IT员工声称TLS 1.1和TLS 1.2正在工作,ASP.NET现在应该默认为这些。但我觉得我们还需要在服务器上安装其他东西,我不知道SSL算法,所以我不知道从哪里开始

var postUrl = new StringBuilder();

//Initialize url with configuration and parameter values...
postUrl.AppendFormat("UN~{0}|", this.MerchantLoginID);
postUrl.AppendFormat("PSWD~{0}|", this.MerchantTransactionKey);
postUrl.Append("TERMS~Y|METHOD~ProcessTranx|TRANXTYPE~Sale|"); 
postUrl.AppendFormat("CC~{0}|", cardNumber);
postUrl.AppendFormat("EXPMNTH~{0}|", expirationMonth.PadLeft(2, '0'));
postUrl.AppendFormat("EXPYR~{0}|", expirationYear);
postUrl.AppendFormat("AMOUNT~{0}|", transactionAmount);
postUrl.AppendFormat("BADDRESS~{0}|", this.AddressLine1);
postUrl.AppendFormat("BADDRESS2~{0}|", this.AddressLine2);
postUrl.AppendFormat("BCITY~{0}|", this.City);
postUrl.AppendFormat("BSTATE~{0}|", this.State);
postUrl.AppendFormat("BZIP~{0}|", this.Zip);
postUrl.AppendFormat("SADDRESS~{0}|", this.AddressLine1);
postUrl.AppendFormat("SADDRESS2~{0}|", this.AddressLine2);
postUrl.AppendFormat("SCITY~{0}|", this.City);
postUrl.AppendFormat("SSTATE~{0}|", this.State);
postUrl.AppendFormat("SZIP~{0}|", this.Zip);
if (!String.IsNullOrEmpty(this.Country))
{
    postUrl.AppendFormat("BCOUNTRY~{0}|", this.Country);
}
if (!String.IsNullOrEmpty(this.Description))
{
    postUrl.AppendFormat("DESCRIPTION~{0}|", this.Description);
}
if (!String.IsNullOrEmpty(this.InvoiceNumber))
{
    postUrl.AppendFormat("INVOICE~{0}|", this.InvoiceNumber);
}
if (this.IsTestMode)
{
    postUrl.AppendFormat("TEST~Y|");
}

//postUrl.Append();

WebClient wClient = new WebClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
String sRequest = "PARMLIST=" + Url.Encode(postUrl.ToString());
wClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
string sResponse = "";
sResponse = wClient.UploadString(PayTraceUrl, sRequest);
另外,仅供参考,当我们连接到第一个Data E4网关时,这个问题也会发生,所以这不仅仅是PayTrace的事情。我的猜测是,随着越来越多的网关关闭对SSL3的访问,我们将继续遇到其他网关的问题,直到在服务器上解决这个问题。此外,我确实在网上找到了一些建议,一些建议在发出出站请求之前放置以下代码:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

不幸的是,这也不起作用,同样的错误。这就是为什么我认为IIS7.5服务器上需要安装一些额外的东西。我只是不知道是什么

这个问题已经解决。结果证明我们的It人员是正确的。服务器上同时安装了TLS 1.1和TLS 1.2。但是,问题是我们的网站以ASP.NET 4.0运行,您必须使用ASP.NET 4.5才能运行TLS 1.1或TLS 1.2。因此,为了解决这个问题,我们的IT人员必须重新启用TLS 1.0以允许与PayTrace的连接

因此,简而言之,错误消息“客户端和服务器无法通信,因为它们没有共同的算法”,是因为服务器上没有可用的SSL协议与PayTrace的服务器通信

更新:
请不要在您的服务器上启用TLS 1.0,这是一个临时修复,不再适用,因为现在有更好的解决方案来确保强大的安全实践。请参阅已接受的答案以获取解决方案。仅供参考,我将把这个答案保留在网站上,因为它提供了问题所在的信息,请不要否决投票

启用TLS1.0也解决了我们的问题(在禁用SSL v3之后)。(服务器2012 R2,使用ASP.net 4.0网站处理PPI支付服务)。这是我用来设置我想要的一切的RegEdit脚本。我们只为客户端而不是服务器禁用了SSL v3,因为这样做破坏了我们尚未准备好处理的其他事情。在我们将站点升级到.Net 4.5.2之后,我们将再次禁用TLS 1.0

此脚本为客户端启用除SSL v3之外的所有协议、服务器和客户端

请务必备份您的注册表


在处理了几天之后,我对问题的最终解决需要两件事

1) 我们将这一行代码添加到所有.Net库中,这些库向其他也禁用了SSL v3的供应商发出绑定api调用

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; // (.Net 4 and below)
2) 这是运行ASP.Net 4.0站点时所需的最终和完整注册表更改,升级到ASP.Net 4.5后需要稍微更改

在我们重新启动服务器之后,所有的问题都消失了

Windows Registry Editor Version 5.00

[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 2.0\Client]
"Enabled"=dword:00000000

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"Enabled"=dword:00000000

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

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

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

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"DisabledByDefault"=dword:00000000

现在还有其他几篇关于这一点的文章,它们都指向启用TLS1.2。任何不安全的东西都是不安全的

您可以在.NET 3.5中使用修补程序来完成此操作。
在.NET4.0和4.5中,只需一行代码就可以做到这一点

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // .NET 4.5 ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // .NET 4.0 在.NET4.6中,它自动使用TLS1.2

有关更多详细信息,请参见此处:

在前面的回答中,有人建议在.Net 4.5中使用这行代码:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // .NET 4.5
我鼓励您在现有价值观的基础上:

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; // .NET 4.5

如果查看值列表,您会注意到它们是二的幂。这样,在将来,例如当事情转移到TLS2.0时,您的代码仍然可以工作

在前面的回答中,丢失了一些可能不存在的注册表项。 它们是SchUseStrongCrypto,必须存在以允许TLS协议正常工作

将注册表项导入注册表后,不需要对代码进行更改,如

ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls

下面是x64 windows操作系统所需的所有注册表项和值。 如果您有32位操作系统(x86),只需删除最后2行即可。 TLS 1.0将被注册表脚本禁用。 需要重新启动操作系统

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
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\server]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[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]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\ssl 3.0\server]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.0\client]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.0\server]
"disabledbydefault"=dword:00000001
"enabled"=dword:00000000

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.1\client]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.1\server]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.2\client]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\tls 1.2\server]
"disabledbydefault"=dword:00000000
"enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319]
"SchUseStrongCrypto"=dword:00000001

在我的例子中,即使项目的目标框架是4.7.1,我仍然会遇到相同的错误,解决方案是将system.web下web.config中的httpRuntime更改为4.7.1

我通过将应用程序从.Net Framework 4.5升级到4.6.2修复了此错误


服务器上正确安装了TLS-1.2,并且禁用了TLS-1.1等旧版本。但是,.Net 4.5不支持TLS-1.2。

我的应用程序正在.Net 4.7.2中运行。最简单的解决方案是将其添加到配置中:

  <system.web>
    <httpRuntime targetFramework="4.7.2"/>
  </system.web>

有两种可能的情况,在我的例子中,我使用了第二点

  • 如果您在生产环境中面临这个问题,并且可以轻松地将新代码部署到生产环境中,那么您可以使用下面的解决方案

    您可以在进行api调用之前添加以下代码行

    ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls12;//。NET 4.5

  • 如果无法部署新代码和
      <system.web>
        <httpRuntime targetFramework="4.7.2"/>
      </system.web>
    
    <runtime>
        <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false"/>
      </runtime>
    
    <runtime>
      <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSystemDefaultTlsVersions=false"
    </runtime>
    
     function Test-SocketSslProtocols {
        
        [CmdletBinding()] 
        param(
            [Parameter(Mandatory=$true)][string]$ComputerName,
            [int]$Port = 443,
            [string[]]$ProtocolNames = $null
            )
    
        #set results list    
        $ProtocolStatusObjArr = [System.Collections.ArrayList]@()
    
    
        if($ProtocolNames -eq $null){
    
            #if parameter $ProtocolNames empty get system list
            $ProtocolNames = [System.Security.Authentication.SslProtocols] | Get-Member -Static -MemberType Property | Where-Object { $_.Name -notin @("Default", "None") } | ForEach-Object { $_.Name }
    
        }
     
        foreach($ProtocolName in $ProtocolNames){
    
            #create and connect socket
            #use default port 443 unless defined otherwise
            #if the port specified is not listening it will throw in error
            #ensure listening port is a tls exposed port
            $Socket = New-Object System.Net.Sockets.Socket([System.Net.Sockets.SocketType]::Stream, [System.Net.Sockets.ProtocolType]::Tcp)
            $Socket.Connect($ComputerName, $Port)
    
            #initialize default obj
            $ProtocolStatusObj = [PSCustomObject]@{
                Computer = $ComputerName
                Port = $Port 
                ProtocolName = $ProtocolName
                IsActive = $false
                KeySize = $null
                SignatureAlgorithm = $null
                Certificate = $null
            }
    
            try {
    
                #create netstream
                $NetStream = New-Object System.Net.Sockets.NetworkStream($Socket, $true)
    
                #wrap stream in security sslstream
                $SslStream = New-Object System.Net.Security.SslStream($NetStream, $true)
                $SslStream.AuthenticateAsClient($ComputerName, $null, $ProtocolName, $false)
             
                $RemoteCertificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$SslStream.RemoteCertificate
                $ProtocolStatusObj.IsActive = $true
                $ProtocolStatusObj.KeySize = $RemoteCertificate.PublicKey.Key.KeySize
                $ProtocolStatusObj.SignatureAlgorithm = $RemoteCertificate.SignatureAlgorithm.FriendlyName
                $ProtocolStatusObj.Certificate = $RemoteCertificate
    
            } 
            catch  {
    
                $ProtocolStatusObj.IsActive = $false
                Write-Error "Failure to connect to machine $ComputerName using protocol: $ProtocolName."
                Write-Error $_
    
            }   
            finally {
                
                $SslStream.Close()
            
            }
    
            [void]$ProtocolStatusObjArr.Add($ProtocolStatusObj)
    
        }
    
        Write-Output $ProtocolStatusObjArr
    
    }
    
    Test-SocketSslProtocols -ComputerName "www.google.com"
    
    Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL