【问题标题】:PowerShell Script digitally signed errorPowerShell 脚本数字签名错误
【发布时间】:2018-03-25 11:18:13
【问题描述】:

我在运行 PowerShell 脚本时遇到错误:

无法加载文件 test_new.ps1。文件 test_new.ps1 未进行数字签名。

我创建了一个 CA 和一个证书,并使用here 描述的过程签署了这个文件。

这是我在MY 目录上执行dir 的时候:

EF76B3D7D8D2406E1F2EE60CC40644B122267F18 CN=PowerShell 用户

我可以看到 test_new.ps1 文件末尾附加的签名块。

这是执行政策和范围:

范围执行政策 ----- --------------- MachinePolicy AllSigned 用户策略未定义 流程绕过 CurrentUser AllSigned LocalMachine 未定义

机器策略应优先设置为AllSigned。一切似乎都很好,为什么我仍然收到数字签名错误。

【问题讨论】:

  • 您是否使用参数-Codesigning 运行dir? CA 证书是否正确导入?
  • 是的,我已经做到了。即使在-Codesigning 之后它也无法正常工作。但我终于想通了。我必须在Trusted Root Certification Authorities 中发布证书。之后它开始工作。请参阅下面的答案

标签: powershell powershell-2.0 powershell-3.0 code-signing


【解决方案1】:

设置为 Allsigned 的 Powershell 执行策略仅运行由受信任的发布者签名的脚本。您可以在下面找到 -ExecutionPolicy 参数的可能值:

受限:默认设置,不加载配置文件或运行脚本。

AllSigned:要求所有脚本和配置文件都由受信任的发布者签名,包括您在本地计算机上编写的脚本。

RemoteSigned:要求从 Internet 下载的所有脚本和配置文件都由受信任的远程发布者签名。

无限制:加载所有配置文件并运行所有脚本。如果您运行从 Internet 下载的未签名脚本,系统会在运行前提示您获得许可。

绕过:没有被阻止,也没有警告或提示。

未定义:从当前作用域中移除当前分配的执行策略,将会话恢复为默认值。此参数不会删除在 Active Directory 组策略中设置的执行策略。

您可以通过如下命令设置 PowerShell 执行策略:

Set-ExecutionPolicy 不受限制

如果您想在域网络上运行脚本,那么您可能会使用组策略来确保用于签署脚本的代码签名证书是您域中受信任的发布者。要做到这一点,有两个步骤:

  1. 导出代码签名证书。

  2. 创建策略并将代码签名证书导入受信任的发布者。

在您的域网络中更新策略后,受信任的发布者证书应列在“证书”管理单元下的“受信任的发布者”中。

【讨论】:

  • 没关系,我知道这一点并且已经尝试过它有效。但我的问题是这是一台域机器,我们需要在不影响安全性的情况下在其上运行。所以我需要对 PS1 文件进行签名,然后将其作为数字签名的可信文件运行。
【解决方案2】:

终于找到了解决办法:

$cert=Get-ChildItem cert:\CurrentUser\MY
$store = New-Object 
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store ("TrustedPublisher" , "LocalMachine")
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()

它必须在TrustedPublisher 商店中发布才能正常工作。

【讨论】:

    【解决方案3】:

    这显然和PowerShell的策略有关,有3个选项,它可以改变这个错误的传递策略和所有相同类型的这个错误。

    1 Set-ExecutionPolicy Bypass -Scope CurrentUser -Force

    2 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force.(推荐)

    3 Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Force。 (不推荐,因为您的计算机环境对恶意软件或任何有害软件的攻击变得很弱......)

    【讨论】:

    • 这不能回答问题。这只是重述了 OP 选择使用RemoteSigned 的原因。
    【解决方案4】:

    编辑 -- 添加一些信息

    其中一种可能的方法完全绕过安全性并像这样启动您的脚本(绕过强加的 GPO,请参阅本文底部):

    PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\path_to_file\test_new.ps1""'}"
    

    在 Windows 2003 域和受限的 powershell 中测试。

    第一次编辑 - 由于评论说不可能,我正在显示我运行脚本的生产系统的屏幕截图:

    在开启旁路的情况下启动 powershell 并执行脚本:

    在不开启 Bypass 的情况下启动 powershell 并执行脚本:

    系统信息:

    第二次编辑 - 由于评论@AnsgarWiechers。 (因为我们谈论的是 Microsoft,所以通常有一种方法可以绕过强加的安全措施。)

    引用评论:

    ...OP 具有通过 GROUP POLICY 强制执行的执行策略(范围 MachinePolicy 和/或 UserPolicy)。哪个不能被绕过...'

    ExecutionPolicy 键由位于注册表配置单元的组策略对象推送:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell

    当您将值从任何更改时,请参阅Possible values for execution policies) 到bypass 的更多信息。然后你可以绕过GPO强加。我敢肯定还有其他方法可以做到这一点。有关更多想法,您可以查看resource。我相信更有创意的人可以找到一些其他方法来绕过 GPO。

    也就是说,对于永久解决方案,最好重复使用。据推测,使用密钥可能更安全,即使您也将取决于其他因素。

    第三次修改 - 证明可以规避 GPO 政策(如果您有足够的权限这样做)

    我终于找到了一些时间来探索这些可能性。对于Windows 2003,无法通过编辑组策略gpedit.msc来更改本地策略,必须在域级别完成(MS不支持Windows 2003,目前为EOL

    Windows 2008 上是不同的故事。

    如果您更改本地策略,您可以轻松地将策略更改为 AllSigned,如下所示:

    PS C:\Windows\system32> Get-ExecutionPolicy -List
    
                                      Scope                         ExecutionPolicy
                                      -----                         ---------------
                              MachinePolicy                               AllSigned
                                 UserPolicy                               AllSigned
                                    Process                                  Bypass
                                CurrentUser                               Undefined
                               LocalMachine                               AllSigned
    

    如果您随后通过上述参数执行脚本:-NoProfile -ExecutionPolicy Bypass,您将收到以下消息,因此您的 GPO 策略需要对脚本进行签名:

    File E:\t\powershell\get_local_admins_computer.ps1 cannot be loaded. The file E
    :\t\powershell\get_local_admins_computer.ps1 is not digitally signed. The scrip
    t will not execute on the system. Please see "get-help about_signing" for more
    details..
        + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordE
       xception
        + FullyQualifiedErrorId : RuntimeException
    

    您还可以检查注册表设置以确保(也将显示您希望在运行脚本后返回的值):

    C:\Windows\system32>REG QUERY HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Win
    dows\PowerShell
    
    HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell
        EnableScripts    REG_DWORD    0x1
        ExecutionPolicy    REG_SZ    AllSigned
    

    如果您有正确的权限,可以通过以下方式轻松规避此问题(这会将 ExecutionPolicy 设置为“绕过”):

       reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell" /f /v "ExecutionPolicy" /t REG_SZ /d "bypass"
        /v ... ValueName
        /t ... type
        /d ... data
        /f ... force (overwrites current value)
    

    然后,如果您检查执行策略,您会发现确实有变化:

    PS C:\Windows\system32> Get-ExecutionPolicy -List

                                  Scope                         ExecutionPolicy
                                  -----                         ---------------
                          MachinePolicy                                  Bypass
                             UserPolicy                               AllSigned
                                Process                                  Bypass
                            CurrentUser                               Undefined
                           LocalMachine                               AllSigned
    

    如果您随后运行该脚本,它将运行良好。

    完成后,您可以通过以下方式返回之前的值:

    reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell" /f /v "ExecutionPolicy" /t REG_SZ /d "AllSigned"
    

    第四次编辑 - 结论

    我想清楚,所以我要添加结论,因为下面的 cmets 可能会导致错误的假设。

    这是参数'-NoProfile -ExecutionPolicy Bypass 将使用的最大安全性:

    PS C:\> Get-ExecutionPolicy -List
    
                                                          Scope                                             ExecutionPolicy
                                                          -----                                             ---------------
                                                  MachinePolicy                                                RemoteSigned
                                                     UserPolicy                                                   AllSigned
                                                        Process                                                   AllSigned
                                                    CurrentUser                                                   AllSigned
                                                   LocalMachine                                                   AllSigned
    

    唯一的情况是你需要一些方法来解决它或拥有一个签名的密钥是当 MachinePolicy 设置为 AllSigned。最佳解决方案是使用密钥。如果由于某种原因不能,您可以使用上述步骤更改注册表中的值或尝试上面已经链接的15 ways to bypass the powershell execution policy 之一。

    【讨论】:

    • 通过组策略强制执行时,绕过执行策略不起作用。
    • @AnsgarWiechers 很抱歉,但在 Windows 2003 R2 Enterprise edition SP2 上根本不是这样 - 将发布从系统制作的屏幕截图。
    • @Tukan:我们的目标是不损害安全性。所以绕过肯定不是一种选择。顺便说一句,正如 Ansgar 指出的那样。绕过在域 PC 上不起作用(通过组策略强制执行)。
    • @user726720 它适用于域 PC。编辑生成的屏幕截图位于域中的服务器上。
    • @user726720 至于安全问题 - 问题是你到底是什么意思。如果您有一次性脚本,那么无论您如何执行脚本,它都是您制作的,安装证书只是意味着额外的工作。如果您有带有证书的恶意脚本也会危及安全性。就我而言,由于政策不允许在生产服务器上添加任何证书,我无法添加证书 - 这是完成工作的唯一方法。没有更改任何设置,只是执行它,工作就完成了。
    【解决方案5】:

    要修复它,您必须运行以下命令来运行 Set-ExecutionPolicy 并更改执行策略设置。

    Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

    【讨论】:

      猜你喜欢
      • 2015-09-04
      • 2018-04-11
      • 2010-11-24
      • 2013-05-06
      • 1970-01-01
      • 2011-10-25
      • 1970-01-01
      • 2011-04-06
      • 1970-01-01
      相关资源
      最近更新 更多