在Invoke-Webrequest呼叫中信任自我签名的证书



问题

有没有一种方法可以调用Invoke-WebRequest,例如,期望证书的给定公共密钥可以验证我信任连接吗?

如果没有,是否有另一种方式调用WebRequest并仅信任网页而不信任发行人或忽略证书检查?

问题

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

由于我没有证书店里的发行人认证Invoke-WebRequest会引发错误:

Invoke-webrequest:根据验证过程,远程证书无效。

已知的解决方法

  1. 使用powershell v6.0.0 Ref
  2. 中添加的-SkipCertificateCheck -Switch
  3. 添加一个新的证书人员来信任所有证书ref
  4. 信任发行人认证

我尝试过但没有奏效

  1. 将网页认证添加到证书存储中,而不信任发行人认证
  2. 将网页认证添加到证书店,并使用-Certificate参数Invoke-WebRequest指定此证书

ps:由于此问题出现在PowerShell< 5和PowerShell Core中,所以我都在标记。

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

对于自签名的证书,由于他们不信任,您是对的,实际上只有2个选项:

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

您无法解决这个基本事实。我喜欢使用以下示例:自签名的证书就像将炸弹形状的物体交付给贴纸上的客户说"不是炸弹 - 相信我,我是@paxz"。证书链就像握住炸弹形对象时一样,您看着送货驱动程序,它们看起来很阴暗,与此同时,看起来不像@paxz那样。然后,您可以选择忽略贴纸,或者接受我可以信任@paxz和阴暗的送货驱动程序。未经明确的同意,您不能仅仅将包裹穿过前门。当您相信整个链条时,贴纸会说"不是炸弹 - 相信我,我已经得到炸弹专家的验证",因为您相信炸弹专家,客户将毫无疑问接受包裹。

我需要与我的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

相关内容

  • 没有找到相关文章

最新更新