【问题标题】:Powershell Invoke-WebRequest Fails with SSL/TLS Secure ChannelPowershell Invoke-WebRequest 使用 SSL/TLS 安全通道失败
【发布时间】:2017-05-27 21:21:54
【问题描述】:

我正在尝试执行这个 powershell 命令

Invoke-WebRequest -Uri https://apod.nasa.gov/apod/

我得到了这个错误。 “Invoke-WebRequest:请求被中止:无法创建 SSL/TLS 安全通道。” https 请求似乎有效(“https://google.com”),但不是这个有问题的请求。我怎样才能让它工作或使用其他 powershell 命令来读取页面内容?

【问题讨论】:

标签: powershell ssl


【解决方案1】:

试试这个

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://apod.nasa.gov/apod/

【讨论】:

【解决方案2】:

为了无耻地窃取一些选票,SecurityProtocol 是一个带有[Flags] 属性的Enum。所以你可以这样做:

[Net.ServicePointManager]::SecurityProtocol = 
  [Net.SecurityProtocolType]::Tls12 -bor `
  [Net.SecurityProtocolType]::Tls11 -bor `
  [Net.SecurityProtocolType]::Tls

或者因为这是 PowerShell,你可以让它为你解析一个字符串:

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"

那么从技术上讲,您不需要知道 TLS 版本。

我从阅读此答案后创建的脚本中复制并粘贴了此内容,因为我不想循环浏览所有可用协议以找到有效的协议。当然,如果您愿意,可以这样做。

最后一点 - 我的 PowerShell 配置文件中有原始(减去 SO 编辑)语句,所以它出现在我现在开始的每个会话中。这并不完全是万无一失的,因为仍然有一些网站失败了,但我肯定很少看到有问题的消息。

【讨论】:

  • 如果您需要访问使用 SSLv3 的站点,那么您需要[Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3"。请记住,由于 POODLE,SSLv3 和 TLSv1.0 已被弃用,因此使用风险自负。
  • 没有办法使用反射来只允许所有 Net.SecurityProtocolType 类型吗?必须有
  • 为什么要默认允许已知有缺陷的协议访问?无论如何,我相信(在撰写本文时)即将发布的 PowerShell V7 将一劳永逸地解决这个问题,而这个问题将慢慢淡出它理所当然且来之不易的遗忘。
  • 在 Windows 上的 Dockerfile 中使用 RUN [Net.ServicePointManager]::SecurityProtocol = 'tls12, tls11, tls' ;单顶点
【解决方案3】:

错误原因是Powershell默认使用TLS 1.0连接网站,但网站安全需要TLS 1.2。您可以通过运行以下任何命令来更改此行为以使用所有协议。您还可以指定单个协议。

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12, [Net.SecurityProtocolType]::Ssl3
[Net.ServicePointManager]::SecurityProtocol = "Tls, Tls11, Tls12, Ssl3"

运行这些命令后,尝试运行你的命令:

Invoke-WebRequest -Uri https://apod.nasa.gov/apod/

然后它会工作。

【讨论】:

    【解决方案4】:

    如果像我一样,上述方法都不起作用,那么单独尝试较低的 TLS 版本可能也值得。我尝试了以下两种方法,但似乎没有解决我的问题:

    [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls
    

    最后,只有当我针对 TLS 1.0(特别是在代码中删除 1.1 和 1.2)时它才起作用:

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

    本地服务器(正在尝试的)在 TLS 1.2 上运行良好,但远程服务器(之前被第三方“确认”在 TLS 1.2 上运行良好)似乎不是。

    希望这对某人有所帮助。

    【讨论】:

      【解决方案5】:

      它对我有用...

      if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
          {
          $certCallback = @"
              using System;
              using System.Net;
              using System.Net.Security;
              using System.Security.Cryptography.X509Certificates;
              public class ServerCertificateValidationCallback
              {
                  public static void Ignore()
                  {
                      if(ServicePointManager.ServerCertificateValidationCallback ==null)
                      {
                          ServicePointManager.ServerCertificateValidationCallback += 
                              delegate
                              (
                                  Object obj, 
                                  X509Certificate certificate, 
                                  X509Chain chain, 
                                  SslPolicyErrors errors
                              )
                              {
                                  return true;
                              };
                      }
                  }
              }
          "@
              Add-Type $certCallback
           }
          [ServerCertificateValidationCallback]::Ignore()
      
      Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
      

      【讨论】:

      • 这个答案有效地禁用了安全检查。虽然它可以消除错误,但它会以许多人认为不可接受的方式打开您的设备攻击面。我永远不会在我拥有的设备上使用它。
      【解决方案6】:

      我还没有弄清楚原因,但重新安装 .pfx 证书(在当前用户和本地机器上)对我有用。

      【讨论】:

      • 您重新安装了哪个 .pfx?
      • @NoRefundsNoReturns 用于发送请求的证书文件。
      • 我仍然不清楚这如何适用于这个问题。
      • @NoRefundsNoReturns 当我在本地 Invoke-WebRequest 时,它起初可以工作,但稍后会失败。似乎有时它无法再读取证书(我不知道它背后的机制。也许这是公司控制的设置)。但是在这种情况下重新安装证书是可行的。
      • 如果您丢失了证书的私钥,这肯定会使证书无法使用,但我怀疑这就是问题所在。如果您丢失了密钥,那么您需要确保保存私钥并将其标记为持久。如果发生这种情况,请提出一个新问题。
      【解决方案7】:

      确保先切换 SHELL:

      SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
      
      RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 
      RUN Invoke-WebRequest -UseBasicParsing -Uri  'https://github.com/git-for-windows/git/releases/download/v2.25.1.windows.1/Git-2.25.1-64-bit.exe' -OutFile 'outfile.exe'
      

      【讨论】:

      • 您是否建议将此额外步骤作为保护原始 PowerShell 会话不使用较弱版本的协议的一种方式?
      猜你喜欢
      • 2018-02-21
      • 2019-06-17
      • 2016-07-15
      • 1970-01-01
      • 2019-05-09
      • 2017-05-25
      • 2021-07-22
      相关资源
      最近更新 更多