如何忽略由未知证书颁发机构签名的SSL证书问题?

6
我正在开发C#应用程序调用Exchange管理Shell Cmdlets。然而,总是出现以下异常:"目标计算机(208.243.XX.2XX:443)上的服务器证书具有以下错误:
SSL证书由未知证书颁发机构签名。
SSL证书包含不匹配主机名的通用名称(CN)。"

但是,我已经编写了代码以接受所有证书,不知道为什么还会出现此错误。

我的代码如下:

    PSCredential credential = new PSCredential("administrator", securePwd);

    WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("https://208.243.49.20/powershell"), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);
    connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;

    Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(connectionInfo);
    PowerShell powershell = PowerShell.Create();
    PSCommand command = new PSCommand();
    command.AddCommand("New-Mailbox");
    command.AddParameter("Name", "TestName");
    powershell.Commands = command;
    ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(
    delegate { return true; }
);
    try
    {
        runspace.Open();//This is where the exception happens
        powershell.Runspace = runspace;
        Collection<PSObject> result= powershell.Invoke();
    }
4个回答

5

WSManConnectionInfo对象有两个属性可以跳过证书检查。

connectionInfo.SkipCACheck = true;

connectionInfo.SkipCNCheck = true;

3

我同意 Brent 的观点,尝试把 ServicePointManager 调用作为第一个调用,在创建 Uri 之前。

但这个委托缺少一些参数。试试这个:

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

嗨,Mike,谢谢你的回复。我把你的代码放在第一行,仍然得到相同的错误。也许这与ServerCertificateValidationCallback无关? - Steven Zack
太棒了!而且比我之前使用的解决方案更短,也不需要额外的命名空间导入。 - Colin

3

我认为Brent是正确的,需要在PowerShell进程中进行。您需要在您的PS中添加以下行:

[System.Net.ServicePointManager]::ServerCertificateValidationCallback += { $true }

我对一个不受信任的SSL站点进行了以下测试,并确认它可以覆盖错误:

$url = "https://www.us.army.mil"
$wc = new-object system.net.webclient
$x = $wc.downloadstring($url) # will fail
[System.Net.ServicePointManager]::ServerCertificateValidationCallback += { $true }
$x = $wc.downloadstring($url) # should succeed

话虽如此,但你说异常发生在打开运行空间时有些奇怪。如果情况是这样的话,也许并不是 PowerShell 代码执行的问题。


太好了!我在 PowerShell 中测试了你的脚本,就像你说的那样,我需要在 PowerShell 中运行它。但是我不知道如何在 PowerShell 进程中添加那一行代码。我写了 command.AddScript("[System.Net.ServicePointManager]::ServerCertificateValidationCallback+={$true}"); 但它没有起作用。如何在 PowerShell 中添加这个脚本呢? - Steven Zack

1

猜测一下:在创建runspace实例之前,也许可以设置ServicePointManager委托。我只是推测,runspace实例的构建可能会捕获并存储来自ServicePointManager的委托。

此外,请确保委托回答的问题是您想要的。它是在问“有效证书”还是在问“无效证书”?如果是后者,则将委托更改为{ return false; }

最后一个问题:PowerShell是否从单独的进程执行?如果是,则ServicePointManager设置将无法帮助您。


感谢您的快速回复。我在创建runspace实例之前移动了ServicePointManager,但仍然出现相同的错误。我将return true更改为return false,但仍然出现相同的错误。我不确定PowerShell是否在单独的进程中执行,但似乎ServicePointManager与此进程无关。如果它是一个单独的进程,我该怎么办?提前致谢。 - Steven Zack
我越来越相信这是因为PowerShell在单独的进程中运行。您需要让PowerShell脚本执行与ServicePointManager配置步骤等效的操作。 - Brent Arias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接