如何仅信任颁发证书(根)而不信任签名证书(叶)本身来验证和运行已签名的PowerShell脚本


  • 我有一个使用PowerShell执行策略AllSigned的Windows映像
  • 我还有一个PowerShell脚本,它由内部CA颁发的签名证书签名
    • 在目标计算机上安装/信任颁发CA的证书
  • 当我签署PowerShell脚本时,我包括了完整的证书链(IncludeChain = 'All')

证书链如下所示:

|- Issuing CA Certificate
|- Signing Certificate

PowerShell脚本由Signing Certificate签名,但我们不会在目标计算机上安装该证书。我们只是将Issuing CA Certificate安装到Trusted Publishers和其他证书存储中。

当我们使用Signing Certificate对自定义应用程序二进制文件进行签名时,此方法有效(我们使用Windows Defender应用程序控制来确保在目标上运行的任何应用程序都由受信任的发布者签名),但在运行PowerShell脚本时,它不起作用

根据MSDN社区的这篇文章,PowerShell使用Known Publisher规则,该规则规定Signing Certificate本身必须在Trusted Publishers证书存储中。

这并不理想,因为我们用来签署PowerShell脚本的签名证书不是我们想要发布的,在我们的产品发布时它也将不再有效。

我知道,如果我在对PowerShell脚本进行签名时使用时间戳服务器,那么如果签名是在签名证书的有效期窗口内生成的,则签名仍将被视为有效,但这不是我们的首选解决方案。

理想情况下,我想知道是否有可能以及如何让PowerShell使用Issuing CA Certificate来验证签名的PowerShell脚本。(即Known Issuer规则)

在不可能的情况下,我想知道为什么Microsoft放弃了允许您在不明确信任签名证书的情况下验证签名的做法(即使用颁发证书来验证它)。

如有任何帮助,我们将不胜感激。

部署和运行PowerShell脚本之间有区别。

令人困惑的是,Windows Defender应用程序控制可以使用两种不同的方式进行代码签名,原因有两种,而PowerShell只支持其中一种。Windows Defender应用程序控制可以使用代码签名:

  1. 使用受信任的颁发CA证书对应用程序进行身份验证。当您的公司希望在所有员工之间轻松共享许多内部应用程序时,就会出现这种情况。它也用于";"可信";Microsoft Store应用程序
  2. 因为";正常的";人们不会盲目信任所有的应用程序和通用证书颁发机构,而是可以基于只信任签名证书进行验证来进行部署。(请参见目录文件)。这样,您就可以部署具有证书的应用程序,这些证书可能没有可访问的CA。例如,如果您使用内部CA签署了应用程序并将其出售给另一家公司,或者您使用的是自签名证书

WindowsDefender应用程序控制主要用于应用程序部署/控制,副产品是它还可以执行PowerShell脚本。大多数";正常的";应用程序可以用";无效";或";破碎的";证书链不完整的证书。该证书仅用于控制代码的分发以及验证应用程序未被篡改/更改,而与活动";运行";代码的。

另一方面,PowerShell在使用AllSigned运行时,总是在运行之前验证整个链。它不关心发行版,只关心运行什么。这意味着整个证书链需要在运行的计算机上存在并受信任。是的,这意味着如果您使用内部CA进行签名,则需要颁发CA证书,以及由运行方分发和信任的签名证书。

这将引导您选择3个选项:

  1. 自签名证书-这对于个人/开发项目来说是可以的,并且比分发未签名的代码稍微好一些
  2. 内部CA证书-这适用于内部项目。在这种情况下,是的,如果你想分发,你必须共享整个证书链
  3. 全球/公共CA证书-如果您是公开/商业发行,这是推荐的方法。公共CA是可信的,代码签名证书可以从DigiCert等地购买,并且可以使用3年。我知道,对我来说,我会觉得运行由DigiCert签名的代码比处理内部或自签名证书更舒服

这没有意义。

如果内部根CA证书在您的受信任的根CA存储中,而中间证书在您受信任的中间存储中。然后,PS脚本由一个具有可信链的证书签名,该证书返回到受信任的根,它应该信任证书的签名。

内部可信CA和公共可信CA之间应该没有区别。

如果说内部CA颁发的代码签名证书比公共签名证书更值得信赖的话。内部流程和控制意味着只有真正受信任的内部发布者才能获得证书,而不是花很少的钱购买的公共代码签名证书。

最新更新