Powershell Invoke-WebRequest通过SSL / TLS安全通道失败


253

我正在尝试执行此powershell命令

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

我得到这个错误。“ Invoke-WebRequest:请求已中止:无法创建SSL / TLS安全通道。” https请求似乎可以正常工作(“ https://google.com ”),但此问题不存在。如何使它工作或使用其他powershell命令读取页面内容?


Answers:


534

尝试使用这个

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

48
默认情况下,powershell使用TLS 1.0,站点安全性要求TLS 1.2
Chandan Rai

3
噢,您如何确定网站的TLS版本?
hewstone

16
尝试使用SSLLabs确定信息: SSL报告:apod.nasa.gov显示TLS1.1和TLS1.2
Christopher G. Lewis

1
有没有办法更持久一些呢?这可行,但似乎在每个控制台窗口中都会重置。
布兰登

3
@Brandon更改它$env:Profile,或者最好编辑注册表
富兰克林于

166

无耻地尝试窃取一些选票,SecurityProtocolEnum具有这一[Flags]属性的。因此,您可以执行以下操作:

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

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

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

这样一来,您从技术上就不需要知道TLS版本。

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

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


7
如果您需要访问使用SSLv3的网站,则需要[Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3"。请记住,由于POODLE而已弃用SSLv3和TLSv1.0,因此使用时需您自担风险。
jordanbtucker

有没有一种方法可以使用反射来仅允许所有Net.SecurityProtocolType类型?必须有
red888

为什么要默认允许已知缺陷的协议访问?无论如何,我相信即将到来的PowerShell V7版本(在撰写本文时)将一劳永逸地解决此问题,并且这个问题将慢慢淡化为应有的和应得的遗忘。
不退款

2

如果像我一样,上述方法均无效,那么仅尝试使用较低的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很好)似乎没有。

希望这对某人有帮助。


1

这个对我有用...

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/

1
该答案有效地禁用了安全检查。虽然它可以消除错误,但是它以许多人认为不可接受的方式打开了设备的攻击面。我永远不会在自己拥有的设备上使用它。
不退款

1

确保先切换外壳:

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'

0

我还没有找出原因,但是重新安装.pfx证书(当前用户和本地计算机中的证书)都对我有用。


您重新安装了哪个.pfx?
不退款

@NoRefundsNoReturns要用于发送请求的证书文件。
斯宾塞

我仍然不清楚这如何适用于这个问题。
不退款

@NoRefundsNoReturns在Invoke-WebRequest本地时,它首先起作用,但以后会失败。似乎有时它无法再读取证书(我不知道其背后的机制。这可能是由公司控制的设置)。但是在这种情况下,重新安装证书即可。
斯宾塞

如果您丢失了证书的私钥,该证书肯定会使证书无法使用,但我怀疑这就是问题所在。如果丢失了密钥,则需要确保要保存私钥并将其标记为永久。提出一个新问题,如果这是正在发生的事情。
不退款
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.