【问题标题】:Invoke-WebRequest SSL fails?Invoke-WebRequest SSL 失败?
【发布时间】:2016-07-15 21:37:11
【问题描述】:

当我尝试使用 Invoke-WebRequest 时,我遇到了一些奇怪的错误:

Invoke-WebRequest -Uri "https://idp.safenames.com/"

Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.

我不确定是什么原因造成的,因为网站本身看起来还不错。

即使 stackoverflow 周围有所有“忽略 ssl 错误”功能,它仍然无法正常工作,让我怀疑它是否与 SSL 有关。

【问题讨论】:

标签: powershell ssl


【解决方案1】:

作为BaconBits notes,.NET 版本 > 4.5 默认使用 SSLv3 和 TLS 1.0。

您可以通过使用 ServicePointManager 类设置 SecurityProtocol 策略来更改此行为:

PS C:\> $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
PS C:\> [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
PS C:\> (Invoke-WebRequest -Uri "https://idp.safenames.com/").StatusCode
200

这将适用于 AppDomain 中的所有请求(因此它仅适用于宿主应用程序的当前实例)。


a module on GitHub 和 PSGallery 现在可以管理这些设置:

Install-Module BetterTls -Scope CurrentUser
Import-Module BetterTls
Enable-Tls -Tls11 -Tls12

【讨论】:

  • 我做错了什么?我真的说不出来...imgur.com/FgHqF1o
  • Powershell 4.0 或 4 0 -1 -1 使用 psversiontable.psversion 查询时
  • 行为再现 2 diff windows box, win8.1 & 10
  • 我们如何知道它是由 TLS 协商过程中的错误引起的?我遇到了这种情况,在我的一生中,无法从 WebException 中得到任何关于 TLS 的信息。该问题仅在自动化测试期间出现,而不是在手动测试期间出现。在客户端,我如何才能收到一条消息,上面写着“客户端尝试与 TLS 1.0 协商,但服务器拒绝了它”。或者对错误的某种伪英语解释,除了“发送时发生意外错误”。另外为什么我的交互式 PS shell 使用 TLS1.2 而新的 powershell.exe 使用 TLS1.0 ?
  • @Cheeso - 你能做的最好的事情(或者更准确地说,唯一的事情)是按照support.microsoft.com/en-us/help/260729/… 启用 SChannel 调试 ...令人讨厌的是,这通常需要重新启动才能真正生效. SChannel 是专用于 SSL/TLS 连接和会话管理的 Windows 子系统,因此任何使用 Windows API 进行 SSL/TLS 连接的东西都将通过它。日志事件进入 Windows 事件查看器日志。应该适用于客户端和服务器。
【解决方案2】:

这也可以永久更改

# set strong cryptography on 32 bit .Net Framework (version 4 and above)
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
# set strong cryptography on 64 bit .Net Framework (version 4 and above)
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

【讨论】:

    【解决方案3】:

    基于 this scan,该 URI 似乎不支持低于 TLS 1.1 的任何内容。

    您使用的是哪个版本的 Windows?如果您使用的是 PowerShell v4.0 或更低版本,您将无法协商 TLS 1.1 或 1.2 连接,因为 .Net Framework 直到 .Net Framework 4.5 才支持 TLS 1.1 或 1.2。 PowerShell v4.0 是 .Net 4.0。这意味着底层 System.Net.WebRequest 类无法协商连接。我相信 PowerShell v5.0 是 .Net 4.5 或 .Net 4.6,但我现在没有 Win 10 客户端来检查 $PSVersionTable

    您可以通过手动编码对 WebRequest 的调用并将协议指定为 [System.Net.SecurityProtocolType]::Tls12[System.Net.SecurityProtocolType]::Tls11 来使其工作,但我不确定这是否可能。如果根据我所看到的安装了.Net 4.5,那应该可以工作,但是,我再一次尝试过。

    作为参考,我在 Windows 7 x64/Powershell v4.0 上得到了与您完全相同的结果,并且我安装了 .Net 4.5,但我从未尝试过手动编码 WebRequest。如果我从here(OpenSSL 0.9.8b,远在 TLS 1.1 和 1.2 之前)将 wget 用于 Windows 1.11.4,我也会收到错误,但如果我从 here 将 wget 用于 Windows 1.17.1,它就可以正常工作(当前,或多或少)。

    【讨论】:

    • 有帮助,但是....原来的问题说I'm not sure what's causing itTeach a person to fish....我们怎么知道这是一个TLS问题?我遇到了这种情况,并且在我的一生中无法从 WebException 中得到任何说“TLS 协商期间出错”的东西。更糟糕的是,问题只出现在自动化测试期间,而不是手动测试期间。在客户端,我如何才能收到一条消息,上面写着“客户端尝试与 TLS 1.0 协商,但服务器拒绝了它”。或者对错误的某种伪英语解释,除了“发送时发生意外错误”。
    • @Cheeso 您通常不会在这里得到有用的错误,因为服务器不会向客户端返回错误。它只是终止连接。客户端所知道的是连接已结束或被拒绝。您需要观察与 Wireshark 的通信,这对 TLS 来说并不好玩。
    【解决方案4】:

    一行:

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

    【讨论】:

      猜你喜欢
      • 2017-05-27
      • 2021-07-22
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 2018-07-19
      相关资源
      最近更新 更多