所以我试图在我的服务器上关闭TLS 1.0和1.1.当我关闭TLS 1.0时,我的应用程序中出现以下错误:
System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.
at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
Run Code Online (Sandbox Code Playgroud)
启用TLS 1.0后一切正常.
现在,调用该服务的代码使用ServicePointManager以下代码指定TLS 1.2 :ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
另一端的服务正在运行.Net 4.6.2,并没有指定使用的TLS协议ServicePointManager,因此根据我的阅读,它将自动检测在此版本的.net框架中运行时需要哪个TLS协议.
有关绑定的WCF服务的Web.config如下
呼叫配置:
<basicHttpBinding>
<binding name="MyBinding" closeTimeout="00:02:00" openTimeout="00:02:00" receiveTimeout="00:02:00" sendTimeout="00:02:00"/>
</basicHttpBinding>
<netTcpBinding>
<binding name="CrossDomainBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
<client>
<endpoint address="net.tcp://MyService.svc"
binding="netTcpBinding" bindingConfiguration="CrossDomainBinding" behaviorConfiguration="CrossDomainBehavior"
contract="MyContract" name="MyBinding">
<identity>
<certificate encodedValue="CERTIFICATEENCODEDVALUE" />
</identity>
</endpoint>
</client>
Run Code Online (Sandbox Code Playgroud)
服务配置:
<bindings>
<netTcpBinding>
<binding>
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehaviour">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="MyCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Run Code Online (Sandbox Code Playgroud)
我不能为我的生活解决这里的问题.
有没有人知道为什么在关闭TLS 1.0时这不起作用?
如您所知,问题是 SSL3 和 TLS1.0 容易受到POODLE攻击,以及其他线程。因此,迁移到支持TLS 1.1 和 TLS 1.2或更高版本的 .NET 4.5 是一个好主意。
基本上,客户端将与服务器协商并采用服务器提供的最高协议。只要服务器提供 TLS 1.1 或 TLS 1.2,客户端就会使用 TLS 1.1 或 1.2。
如果您的应用程序是 .NET 4.0,您仍然可以通过在服务器上安装 .NET 4.5 来使用 TLS 1.2。您的应用程序不必重新定位到 .NET 4.5。您可以强制更改 .NET 4.0 应用程序中的协议,如下所示(并且已经这样做了):
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;//SecurityProtocolType.Tls1.2;
Run Code Online (Sandbox Code Playgroud)
需要注意的是,仅仅升级到 .NET 4.5 并不能自动解决问题。这是因为.NET 4.0 / 4.5中的默认协议是 SSL3/TLS1.0。因此,为了在 .NET 4.5+ 中使用 TLS 1.2 或 TLS 1.1,您需要在任何 WebRequest 调用之前设置 SecurityProtocol(使用SslProtocols 枚举或相应的整数值)(实际上,每个 AppDomain 仅需执行一次此操作)。不过重新设置一下也没什么坏处)。
首先,TLS 在 Windows 中由一个名为 SChannel 的组件终止。支持的密码取决于 SChannel 的版本,而 SChannel 则取决于操作系统,而不是 .NET 版本;例如,Windows XP 仅支持 TLS 1.0。参考号
由于Windows Server 2012 和 Windows 8.1 TLS 1.2 默认启用。所以,你应该没问题。
但是,值得检查是否在操作系统级别和注册表中启用了 TLS 1.2 (这也会影响IIS (7.x)、SQL Server (2012)、Reporting Services等,具体取决于构建版本)。默认安全协议取决于以下注册表项。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319: SchUseStrongCrypto to DWORD 1
Run Code Online (Sandbox Code Playgroud)
检查注册表项“SchUseStrongCrypto”是否设置为 1。这将强制 .NET 应用程序避免使用 SSL3.0 或 TLS1.0 并始终使用可用的最强协议。
我希望这有帮助!