【问题标题】:Trusting self-signed certificate in Invoke-WebRequest call在 Invoke-WebRequest 调用中信任自签名证书
【发布时间】:2019-10-08 23:29:22
【问题描述】:

问题

有没有办法可以调用Invoke-WebRequest,例如期望证书的给定公钥来验证我是否信任连接?

如果没有,是否有另一种方法来调用 webrequest 并且只信任网页而不信任颁发者或忽略证书检查?

问题

我想用Invoke-WebRequest 加载网页。我尝试通过 https 连接到网页,服务器提供了自签名证书。

由于我的证书库中没有颁发者证书Invoke-WebRequest 将引发错误:

Invoke-WebRequest : 根据验证程序,远程证书无效。

已知的解决方法

  1. 使用在 Powershell v6.0.0 中添加的-SkipCertificateCheck-Switch ref
  2. 添加新的 Certificatepolicy 以信任所有证书 ref
  3. 信任颁发者证书

我试过但没有成功

  1. 在不信任颁发者证书的情况下将网页证书添加到证书存储区
  2. 将网页证书添加到证书存储区并使用Invoke-WebRequest 的-Certificate-参数指定此证书

PS:由于这个问题同时出现在 Powershell

【问题讨论】:

    标签: powershell https ssl-certificate powershell-core


    【解决方案1】:

    简短的回答,不,你无法绕过它,当涉及到证书时,甚至不要尝试。客户端将首先查看证书,以及整个证书链以查看它是否受信任。如果该链的任何部分(例如发行者)不可信,则它不可信。如果这个基本事实没有发生,那么就没有办法撤销证书。

    对于自签名证书,由于它们不受信任,所以您是对的,客户端实际上只有 2 个选项:

    1. 忽略证书来源,使用-SkipCertificateCheck开关盲目连接。
    2. 接受发行者和全链可以信任并导入证书

    你无法绕过这个基本事实。我喜欢用这个例子:自签名证书就像向客户交付一个炸弹形状的物体,上面贴着“不是炸弹——相信我,我是@Paxz”的标签。证书链就像拿着炸弹形状的物体,你看看送货司机,它们看起来很阴暗,同时看起来一点也不像@Paxz。然后,您可以选择忽略贴纸,或者接受我可以信任 @Paxz 和阴暗的送货司机。您不能在没有明确同意的情况下将包裹推入前门。当您信任整个链条时,贴纸会显示“Not a Bomb - Trust me, I've been verifyed by Bomb Experts”,因为您信任 Bomb Experts,客户将毫无疑问地接受包裹。

    【讨论】:

    • 嗯.. 我希望得到不同的答案... :'D 但我担心结果会这样。我将再等一周,希望有其他事情出现,如果没有,我会将这个答案标记为正确(在那之前,请接受我的投票)。另外,谢谢你的轶事!
    【解决方案2】:

    我需要与我的 Icinga2 服务器建立可信连接,并找到了一种比较单个证书的方法。

    这是存储 [X509Certificate2] 证书以供比较并设置回调函数以验证证书的主要代码。

    function set-SSLCertificate {
        param(
            $Cert
        )
    
        if (-not("validateCert" -as [type])) {
            add-type -TypeDefinition @"
                using System.Net.Security;
                using System.Security.Cryptography.X509Certificates;
    
                public static class ValidateCert {
                    static X509Certificate2 MyCert;
    
                    public static bool Validate(object sender,
                        X509Certificate cert,
                        X509Chain chain,
                        SslPolicyErrors sslPolicyErrors) {
                            if (MyCert.Equals(cert)) {
                                return true;
                            } else {
                                return false;
                            }
                    }
    
                    public static RemoteCertificateValidationCallback GetDelegate(X509Certificate2 Cert) {
                        MyCert = Cert;
                        return new RemoteCertificateValidationCallback(ValidateCert.Validate);
                    }
                }
    "@
        }
        [System.Net.ServicePointManager]::ServerCertificateValidationCallback = [validateCert]::GetDelegate($Cert)
    }
    

    您需要一个证书为 [X509Certificate2]。

    我使用这个函数来转换一个易于存储在变量中的 Base64 格式的证书。

    function get-x509 {
        param(
            [string]
                $Cert64
        )
    
        $CertBin=[System.Convert]::FromBase64String(($Cert64.Trim(" ") -replace "-.*-",""))
    
        [System.Security.Cryptography.X509Certificates.X509Certificate2]$CertBin
    }
    

    连接 SSL 服务器的整个过程:

    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
    
    $SecPass = ConvertTo-SecureString $Pass -AsPlainText -Force
    $Cred = New-Object System.Management.Automation.PSCredential($User, $SecPass)
    
    $Cert = get-x509 $Cert64
    set-SSLCertificate $Cert
    
    Invoke-RestMethod -Uri $URL -Credential $Cred
    

    获取旧行为:

    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 2016-11-29
      • 2019-09-03
      • 1970-01-01
      • 2016-07-27
      • 2018-03-20
      相关资源
      最近更新 更多