【问题标题】:Can't download files from the computer with enabled TLS 1.1/1.2 protocols using WebClient.DownloadFile method无法使用 WebClient.DownloadFile 方法从启用了 TLS 1.1/1.2 协议的计算机下载文件
【发布时间】:2015-03-14 07:55:31
【问题描述】:

我正在尝试实现一个简单的控制台应用程序,以通过 TLS 1.1/1.2 协议使用 Webclient.DownloadFile 方法下载文件。 这是应用程序的代码:

var downloadUrl = "https://serverURL.com/sample.mp3";
var filename = "sample.mp3";
var myWebClient = new WebClient();
myWebClient.DownloadFile(downloadUrl, filename);

每次我运行它时都会收到以下错误消息:

Unhandled Exception: System.Net.WebException: 
The underlying connection was closed: An unexpected error occurred on a receive. --->   

System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possessa common algorithm
at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface SecModule, String package, CredentialUse intent, SecureCredential scc)
at System.Net.Security.SecureChannel.AcquireCredentialsHandle(CredentialUse credUsage, SecureCredential& secureCredential)
at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[]& thumbPrint)
at System.Net.Security.SecureChannel.GenerateToken(Byte[] input, Int32 offset, Int32 count, Byte[]& output)
at System.Net.Security.SecureChannel.NextMessage(Byte[] incoming, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Net.WebClient.DownloadFile(Uri address, String fileName)
at System.Net.WebClient.DownloadFile(String address, String fileName)
at web_downloader.Program.Main(String[] args) in c:\Users\user\Documents\Visual Studio 2013\Projects\web_downloader\web_downloader\Program.cs:line 27

我有以下设置:web_downloader 应用程序位于 ServerA(Windows Server 2012 R2/64 位)上,它在 HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control 下的注册表项中有以下内容/SecurityProviders/SCHANNEL/协议

PCT 1.0
--Client
----DisabledByDefault=1
----Enabled=0
--Server
----DisabledByDefault=1
----Enabled=0
SSL 2.0
--Client
----DisabledByDefault=1
----Enabled=0
--Server
----DisabledByDefault=1
----Enabled=0
SSL 3.0
--Client
----DisabledByDefault=1
----Enabled=0
--Server
----DisabledByDefault=1
----Enabled=0
TLS 1.0
--Client
----DisabledByDefault=1
----Enabled=0
--Server
----DisabledByDefault=1
----Enabled=0
TLS 1.1
--Client
----DisabledByDefault=0
----Enabled=1
--Server
----DisabledByDefault=0
----Enabled=1
TLS 1.2
--Client
----DisabledByDefault=0
----Enabled=1
--Server
----DisabledByDefault=0
----Enabled=1

ServerB,存储sample.mp3文件,有以下内容:

SSL 2.0
  Client
    DisabledByDefault=1
TLS 1.1
  Client
    DisabledByDefault=0
    Enabled=1
  Server
    DisabledByDefault=0
    Enabled=1
TLS 1.2
  Client
    DisabledByDefault=0
    Enabled=1
  Server
    DisabledByDefault=0
    Enabled=1

只要我在 ServerA 上启用 TLS 1.0,我就可以从 ServerB(Windows 7/64bit/Net Framework 4.5.1)下载 mp3 文件,而无需任何问题。

系统加密:使用符合 FIPS 的算法进行加密、散列和签名策略在两台计算机上均已禁用。

我是否缺少与 TLS 1.1/1.2 一起使用的 DownloadFile 方法的任何配置参数?

【问题讨论】:

    标签: c# .net iis ssl downloadfile


    【解决方案1】:

    .NET Framework 使用自己的设置来决定默认使用哪些 HTTPS 版本。请参阅 https://stackoverflow.com/a/169396/126229 以了解要在客户端上设置的 ServicePointManager.SecurityProtocol 设置,以确保它尝试协商 TLS1.1 连接。

    您还可以使用 Fiddler 观察出站流量(查看 CONNECT Tunnel 的 TextView 请求检查器)以了解 ClientHello 消息的细分。请注意,在启用 HTTPS 解密的情况下运行 Fiddler 会产生干扰,因为 Fiddler 本身默认使用 SSL3+TLS1 与服务器通信。

    【讨论】:

    • 我关注了包含链接中的所有链接,但没有一个提供这样的例子——甚至在 MSDN 上也没有(他们的例子甚至不包括页面上的枚举) .我正在尝试让 MSDeploy、ClickOnce 和 .NET 远程处理通过 TLS 1.2 工作。到目前为止,我发现的唯一解决方案是在客户端和服务器的组策略中强制执行 FIPS 算法。但这意味着要更改大量代码以确保我可以在所有应用程序中使用符合 FIPS 的算法(并希望客户端不会影响 3rd 方应用程序)。
    【解决方案2】:

    如果您使用 .NET Framwork 3.5 或更低版本,则只能设置 TLS 1.0(放置注册表项),并且必须在服务器上启用 TLS 1.0。

    【讨论】:

      猜你喜欢
      • 2017-05-12
      • 1970-01-01
      • 2017-02-23
      • 2016-08-15
      • 2018-02-07
      • 2015-11-30
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      相关资源
      最近更新 更多