当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

作者:精品下载站 日期:2024-12-14 22:58:36 浏览:16 分类:玩电脑

如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?


带有数字签名的脚本或可执行文件允许用户确保文件是原始的并且其代码未被第三方更改。当前版本的 PowerShell 具有使用数字证书对 *.ps1 脚本文件进行代码签名的内置工具。

您可以使用特殊类型的证书(代码签名)对 PowerShell 脚本进行签名。该证书可以从外部商业证书颁发机构 (AC)、内部企业 CA 获取,也可以使用自签名证书。

假设您的域中部署了 PKI 服务(Active Directory 证书服务)。让我们通过访问 https://CA-server-name/certsrv 并使用代码签名模板请求新证书(必须首先在证书颁发机构控制台中启用此模板)来请求新证书。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

此外,用户还可以从 mmc 管理单元“证书”->“我的帐户”->“个人”->“所有任务”->“请求新证书”请求用于签署 PowerShell 脚本的证书。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

如果您手动请求证书,您应该拥有扩展名为 .cer 的 x509 证书文件。该证书必须安装在您计算机的本地证书存储中。

您可以使用以下 PowerShell 命令将证书添加到计算机的受信任根证书中:

$certFile = Export-Certificate -Cert $cert -FilePath C:\ps\certname.cer
Import-Certificate -CertStoreLocation Cert:\LocalMachine\AuthRoot -FilePath $certFile.FullName

如果要使用自签名证书,请使用 New-SelfSignedCertificate cmdlet 创建 DNS 名称为 testPC1 的 CodeSigning 证书:

New-SelfSignedCertificate -DnsName testPC1 -Type CodeSigning
$cert = New-SelfSignedCertificate -Subject "Cert for Code Signing” -Type CodeSigningCert -DnsName test1 -CertStoreLocation cert:\LocalMachine\My

生成证书后,使用证书管理器控制台 (

certmgr.msc

)。

获得证书后,您可以配置 PowerShell 脚本执行策略以仅允许运行签名的脚本。默认情况下,Windows 10/Windows Server 2016 上的 PowerShell 执行策略设置为受限(阻止任何 PowerShell 脚本的执行)。

File C:\ps\script.ps1 cannot be loaded because running scripts is disabled on this system.

要仅允许运行已签名的 PS1 脚本,您可以将 PowerShell Eecution Policy 更改为 AllSigned 或 RemoteSigned(唯一的区别是 RemoteSigned 仅需要从 Internet 下载的脚本的签名):

Set-ExecutionPolicy AllSigned -Force

在此模式下,运行未签名的PowerShell脚本时,会出现错误:

File C:\script.ps1 cannot be loaded. The file script.ps1 is not digitally signed. You cannot run this script on the current system.

您还可以使用计算机配置 -> 策略 -> 管理模板 -> Windows 组件 -> Windows PowerShell 下的打开脚本执行组策略参数来允许签名的 PowerShell 脚本运行。将参数值更改为仅允许签名脚本

现在让我们继续签署 PowerShell 脚本文件。首先,您需要从当前用户的本地证书存储中获取CodeSign证书。首先,让我们列出所有可用于签署代码的证书:

Get-ChildItem cert:\CurrentUser\my -CodeSigningCert

在我们的例子中,我们将从个人用户证书存储中获取第一个证书并将其保存在 $cert 变量中:

$cert = (Get-ChildItem cert:\CurrentUser\my -CodeSigningCert)[0]

如果您已将证书移至受信任的根证书存储,请使用以下命令:

$cert = (Get-ChildItem Cert:\LocalMachine\AuthRoot -CodeSigningCert)[0]

然后,您可以使用此证书通过 PowerShell 脚本对 PS1 文件进行签名:

Set-AuthenticodeSignature -Certificate $cert -FilePath C:\PS\testscript.ps1

您还可以使用以下命令(在本例中,我们选择之前由 DnsName 创建的自签名证书):

Set-AuthenticodeSignature C:\PS\test_script.ps1 @(gci Cert:\LocalMachine\AuthRoot -DnsName testPC1 -codesigning)[0]

提示。 Set-AuthenticodeSignature cmdlet 有一个特殊的 TimestampServer 参数,用于指定服务时间戳的 URL。如果该参数留空,PS脚本将在证书过期后停止运行。例如,您可以按如下方式设置时间戳服务器:

-TimestampServer "http://timestamp.verisign.com/scripts/timstamp.dll"

如果您尝试使用通用 SSL/TLS 证书对脚本进行签名,则会出现错误:

Set-AuthenticodeSignature: Cannot sign code. The specified certificate is not suitable for code signing.

您可以一次对文件夹中的所有 PowerShell 脚本文件进行签名:

Get-ChildItem c:\ps\*.ps1| Set-AuthenticodeSignature -Certificate $Cert

现在您可以检查 PowerShell 脚本文件是否已正确签名。您可以使用 Get-AuthenticodeSignature cmdlet 或打开 PS1 文件属性并转到数字签名选项卡。

Get-AuthenticodeSignature c:\ps\test_script.ps1 | ft -AutoSize

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

如果

UnknownError

执行 Set-AuthenticodeSignature 命令时出现警告,则该证书不受信任,因为位于用户的个人证书存储中。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

您需要将其移至受信任的根证书(不要忘记定期检查 Windows 证书存储中是否有可疑证书并更新受信任的根证书列表):

Move-Item -Path $cert.PSPath -Destination "Cert:\LocalMachine\Root"

现在,在验证 PS1 文件的签名时,应返回 Valid 状态。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

对 PowerShell 脚本文件进行签名时,Set-AuthenticodeSignature cmdlet 会将数字签名块添加到 PS1 文本文件的末尾:

# SIG # Begin signature block
...........
...........
# SIG # End signature block

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

签名块包含脚本的哈希值,该哈希值使用私钥加密。

第一次尝试运行脚本时,会出现警告:

Do you want to run software from this untrusted publisher?
File C:\PS\script.ps1 is published by CN=testPC1 and is not trusted on your system. Only run scripts from trusted publishers.

如果您选择[A]始终在第一次运行脚本时运行,则下次运行使用此证书签名的脚本时,将不再出现警告。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

为了防止出现此警告,您还需要将证书复制到受信任的发布者证书颁发机构。使用证书控制台中的复制粘贴操作将证书复制到受信任的发布者 -> 证书。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

签名的 PowerShell 脚本现在将运行,而不显示不受信任的发布者通知。

提示。 CA 根证书和用于签署脚本的证书必须是可信的(否则,脚本将无法运行)。您可以使用 GPO 将证书集中部署到域计算机。证书需要放置在 GPO 的以下公钥部分:计算机配置 -> 策略 -> Windows 设置 -> 安全设置 -> 公钥策略 -> 受信任的根证书颁发机构受信任的发布者

如果根证书不受信任,那么当您运行PowerShell脚本时,会出现错误:

A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

如果更改签名的 PowerShell 脚本文件的代码会发生什么?运行它的尝试将被阻止,并收到脚本内容已更改的通知。

File xx.ps1 cannot be loaded. The contents of file xx.ps1 might  have been changed by an unauthorized user or process, because the hash of the file does not match the hash stored in the digital signature. The script cannot run on the specified system.

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

尝试使用 Get-AuthenticodeSignature cmdlet 验证脚本的签名。如果计算出的哈希值与签名中的哈希值不匹配,则消息

HashMismatch

出现。

[玩转系统] 如何使用代码签名证书对 PowerShell 脚本 (PS1) 进行签名?

因此,对已签名 PS1 脚本的代码进行任何修改都需要重新签名。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯