为什么我的证书不能用于 PowerShell 代码签名?

Why my certificate can't be used for PowerShell code signing?

Windows 7 x64,PowerShell 4.0。

我是使用数字签名的初学者,因此我之前阅读了这些文章:

我需要签署我的 PowerShell 脚本。我们 Windows 域的所有用户都可以访问这些脚本。但是一开始想在电脑上学做。

我将执行策略设置为 AllSigned 值(具有管理员权限):

Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy AllSigned

根据 Don Jones 的文章,我创建了自己的证书(通过 VS2015 的开发人员命令提示 [即通过 cmd.exe],具有管理员权限):

cd c:\temp
makecert -n "CN=Andrey Bushman" -a md5 -r -sv Andrey.Bushman.pvk -ss Root -sr localMachine Andrey.Bushman.cer

我在当前目录中得到了 Andrey.Bushman.cerAndrey.Bushman.pvk 文件。第一个大小为 1 kb,第二个大小为 2 kb。所以,我看到私钥的大小大于证书的大小。

问题 #1
这是否意味着我的证书不包含我的私钥副本?

现在我在证书库中看到新项目:

PS Cert:\LocalMachine\Root> Get-ChildItem | where -Property Issuer -EQ "CN=Andrey Bushman"

  Directory: Microsoft.PowerShell.Security\Certificate::LocalMachine\Root

Thumbprint                                Subject                                                          
----------                                -------                                                          
CF26A00BB7C8EB2B1EA66CA307C4B5025F636F9A  CN=Andrey Bushman                                                

然后 Don Jones 做到了:

makecert -pe -n "CN=MyCertificate" -ss MY 
–a sh1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk 
–c root.cer

问题 #2
他为什么这样做?在他这样做之前,我们已经在 cert:LocalMachine\Root 存储中有了我们的证书。

以此类推,我为我的案例做了:

makecert -pe -n "CN=Andrey Bushman" -ss MY -a md5 -iv Andrey.Bushman.pvk -ic Andrey.Bushman.cer

但是当我启动这个时 什么都没有:

gci cert:\CurrentUser\My -codesigning

没有 -codesigning 标志我得到这个:

PS C:\temp> gci cert:\CurrentUser\My

  Directory: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                                Subject                                                          
----------                                -------                                                          
8F0D753ACA7F6631C3D967921BD06E158E1AB1AF  CN=Andrey Bushman

问题 #3
为什么我使用 -codesigning 标志时什么也得不到?

好的,我尝试签署一些文件并解决问题:

PS C:\temp> $cert = @(gci cert:\CurrentUser\My)[0]

PS C:\temp> Set-AuthenticodeSignature -FilePath .3.ps1 -Certificate $cert
Set-AuthenticodeSignature : It isn't possible to sign the code. The specified certificate isn't suitable for the code signing
а.
line:1 char:1
+ Set-AuthenticodeSignature -FilePath .3.ps1 -Certificate $cert
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Set-AuthenticodeSignature], PSArgumentException
    + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.SetAuthenticodeSignatureCommand

问题 #4
如何使我的证书适合代码签名?

UPD
我不能问我的问题 here,因为我不能在该网站上注册(我的电子邮件中没有任何内容)。我写信给支持团队的电子邮件,但他们从不回音。几年前我试过,几天前我又试过,但我得到了同样的结果。

Q1: Does it mean that my certificate don't include the copy of my private key?

A1:是的。证书可以在 周围交换,因为 它们不包含私钥。私钥通常只存在于一台计算机上,备份副本存档在安全位置。任何可以访问私钥的人都可以签署他们想要的任何东西,看起来就像你所做的一样。 (此问题的更完整答案不在 Stack Overflow 的典型范围内,但 PKI 上有许多可用资源。)

Q2: Why he did it?
Q3: Why I get nothing when I use the -codesigning flag?

A2/A3:他运行makecert第一次创建根证书。根证书专门用于颁发其他证书,这就是它不显示为代码签名证书的原因。这第二次,他正在制作实际的证书。 -eku 选项指定要使用的证书选项,可以是从根证书、代码签名证书或数字签名到更高级的内容(如数据加密或客户端身份验证)的任何内容。

Q4: How can I make my certificate suitable for the code signing?

A4:我在 makecert.exe 方面经验不多,因为我的公司与 Cyber​​trust 签订了合同,因此我可以根据需要生成尽可能多的证书,而不必担心每个证书的成本. (是的,这是一种奢侈。)这意味着我无法回答有关 makecert.exe、其语法或要使用的 -eku 选项的问题。

在很多方面,makecert在幕后为你做了很多事情,但你需要的基本东西是一样的:

  1. 您必须生成一个 public / 私钥对。
  2. 您必须创建指定 "code signing" 的证书请求。
  3. 您必须使用私钥签署您的证书请求。
  4. 证书颁发机构使用该请求生成证书。
  5. 只能使用签署请求的私钥安装生成的证书。
  6. 安装证书后,它将使用 -codesigning 选项显示,并且可供 Set-AuthenticodeSignature 使用。

我建议使用 makecert 文档和其他数字证书资源来找到正确的选项,但根据我对您发布的链接的快速浏览,您似乎拥有所需的大部分信息.从事数字证书多年以来,在我看来,对您有帮助的最重要的事情就是更加熟悉 Public 密钥基础设施 (PKI) 的工作原理,尤其是关于证书链的工作原理和已验证。完成这一切需要时间,而且在 Powershell 中进行代码签名并不是最容易开始的地方,但如果您要进行大量操作,那么值得投入时间。