如何在Windows上创建用于代码签名的自签名证书?


Answers:


363

更新的答案

如果您使用以下Windows版本或更高版本:Windows Server 2012,Windows Server 2012 R2或Windows 8.1,则现在不建议使用MakeCert,并且Microsoft建议使用PowerShell Cmdlet New-SelfSignedCertificate

如果您使用的是Windows 7等旧版本,则需要坚持使用MakeCert或其他解决方案。有人建议使用公钥基础结构Powershell(PSPKI)模块

原始答案

虽然您可以一次性创建一个自签名代码签名证书(SPC- Software Publisher Certificate),但我更喜欢执行以下操作:

创建自签名证书颁发机构(CA)

makecert -r -pe -n "CN=My CA" -ss CA -sr CurrentUser ^
         -a sha256 -cy authority -sky signature -sv MyCA.pvk MyCA.cer

(^ =允许批处理命令行换行)

这将创建一个带有可导出私钥(-pe)的自签名(-r)证书。它的名称为“我的CA”,应放在当前用户的CA存储中。我们正在使用SHA-256算法。该密钥用于签名(-sky)。

私钥应存储在MyCA.pvk文件中,证书应存储在MyCA.cer文件中。

导入CA证书

因为如果您不信任CA证书就没有意义,因此需要将其导入Windows证书存储区。您可以使用“证书” MMC管理单元,但可以从命令行使用:

certutil -user -addstore Root MyCA.cer

创建代码签名证书(SPC)

makecert -pe -n "CN=My SPC" -a sha256 -cy end ^
         -sky signature ^
         -ic MyCA.cer -iv MyCA.pvk ^
         -sv MySPC.pvk MySPC.cer

与上面的内容几乎相同,但是我们提供了颁发者密钥和证书(-ic和-iv开关)。

我们还希望将证书和密钥转换为PFX文件:

pvk2pfx -pvk MySPC.pvk -spc MySPC.cer -pfx MySPC.pfx

如果要保护PFX文件,请添加-po开关,否则PVK2PFX将创建没有密码短语的PFX文件。

使用证书签名代码

signtool sign /v /f MySPC.pfx ^
              /t http://timestamp.url MyExecutable.exe

看看为什么时间戳很重要

如果将PFX文件导入证书存储(可以使用PVKIMPRT或MMC管理单元),则可以按以下方式签名代码:

signtool sign /v /n "Me" /s SPC ^
              /t http://timestamp.url MyExecutable.exe

以下是一些可能的时间戳URL signtool /t

  • http://timestamp.verisign.com/scripts/timstamp.dll
  • http://timestamp.globalsign.com/scripts/timstamp.dll
  • http://timestamp.comodoca.com/authenticode

完整的Microsoft文档

资料下载

对于不是.NET开发人员的用户,您将需要Windows SDK和.NET框架的副本。当前链接位于此处:SDK&.NET(在中安装makecert C:\Program Files\Microsoft SDKs\Windows\v7.1)。你的旅费可能会改变。

可从Visual Studio命令提示符中获得MakeCert。Visual Studio 2015确实具有此功能,可以从Windows 7的“开始菜单”下的“ VS 2015开发人员命令提示符”或“ VS2015 x64本机工具命令提示符”(可能它们都在同一个文件夹中)启动。


是否可以使用此方法填充证书的电子邮件地址字段?右键单击exe>属性>数字签名,签名后将电子邮件显示为“不可用”。
cronoklee 2012年

如果出现“参数过多”错误,则说明您没有意外地删除连字符之一。失败-重新输入连字符-不要复制粘贴。
2012年

8
@cronoklee要填充证书的电子邮件字段,只需添加E=your@email。例如:makecert -pe -n "CN=My SPC,E=email@domain" ........
Rob W

1
您是否不需要扩展使用密钥标志,-eku 1.3.6.1.5.5.7.3.3以便可以将该证书用于代码签名(我知道Powershell如果缺少它,就无法对脚本进行签名)
Scott Chamberlain

1
@ AdamPhelps,Windows不会“学习”以信任您的证书。您的用户需要在根存储中安装CA证书。一般来说,这是个坏主意(因为根CA证书可用于恶意目的)。不过,在企业场景中这可能很有意义。
罗杰·利普斯科姆2014年

36

如答案中所述,为了使用一种不建议使用的方式来签名自己的脚本,应该使用New-SelfSignedCertificate

  1. 生成密钥:
New-SelfSignedCertificate -DnsName email@yourdomain.com -Type CodeSigning -CertStoreLocation cert:\CurrentUser\My
  1. 导出不带私钥的证书:
Export-Certificate -Cert (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)[0] -FilePath code_signing.crt

如果您有多个证书,则[0]可使此功能有效。显然,使索引与要使用的证书相匹配...或使用过滤方式(通过指纹或发行方)。

  1. 将其导入为受信任的发布者
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\TrustedPublisher
  1. 将其导入为根证书颁发机构。
Import-Certificate -FilePath .\code_signing.crt -Cert Cert:\CurrentUser\Root
  1. 对脚本签名(假设此处名为script.ps1,并相应地修复路径)。
Set-AuthenticodeSignature .\script.ps1 -Certificate (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)

显然,一旦设置了密钥,就可以使用它对其他脚本进行签名。
您可以在本文中获得更多详细信息和一些故障排除帮助。


谢谢你这个 我应该先从最底层的答案开始!
mdiehl13 '18

谢谢。这解决了我试图使这个“看似简单”的过程正常工作的所有问题。
戴夫

1
我在“ 2”上遇到错误。由于(get-ChildItem ...)返回了多个证书,因此我在末尾加上了“ [0]”,它起作用了。就像Export-Certificate -Cert (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)[0] -FilePath code_signing.crt
lundman '18

1
@Lara感谢您的反馈,我添加了一些上下文信息,即使在尝试使用低咖啡因含量时也更容易;-)
chaami 19/12/5

1
@Lara感谢您的信号,我在编辑时没有特别注意,似乎StackOverflow现在对块的语法更加挑剔,并且在代码开始之前需要换行。
chaami

21

罗杰的回答很有帮助。

但是,我在使用它时遇到了一些麻烦,并一直显示红色的“ Windows无法验证此驱动程序软件的发行者”错误对话框。关键是使用以下命令安装测试根证书

certutil -addstore Root Demo_CA.cer

罗杰的答案还没有涵盖。

这是一个对我有用的批处理文件(带有我的.inf文件,不包括在内)。它显示了如何从头到尾完成所有操作,完全没有GUI工具(除了一些密码提示)。

REM Demo of signing a printer driver with a self-signed test certificate.
REM Run as administrator (else devcon won't be able to try installing the driver)
REM Use a single 'x' as the password for all certificates for simplicity.

PATH %PATH%;"c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin";"c:\Program Files\Microsoft SDKs\Windows\v7.0\Bin";c:\WinDDK\7600.16385.1\bin\selfsign;c:\WinDDK\7600.16385.1\Tools\devcon\amd64

makecert -r -pe -n "CN=Demo_CA" -ss CA -sr CurrentUser ^
   -a sha256 -cy authority -sky signature ^
   -sv Demo_CA.pvk Demo_CA.cer

makecert -pe -n "CN=Demo_SPC" -a sha256 -cy end ^
   -sky signature ^
   -ic Demo_CA.cer -iv Demo_CA.pvk ^
   -sv Demo_SPC.pvk Demo_SPC.cer

pvk2pfx -pvk Demo_SPC.pvk -spc Demo_SPC.cer ^
   -pfx Demo_SPC.pfx ^
   -po x

inf2cat /drv:driver /os:XP_X86,Vista_X64,Vista_X86,7_X64,7_X86 /v

signtool sign /d "description" /du "www.yoyodyne.com" ^
   /f Demo_SPC.pfx ^
   /p x ^
   /v driver\demoprinter.cat

certutil -addstore Root Demo_CA.cer

rem Needs administrator. If this command works, the driver is properly signed.
devcon install driver\demoprinter.inf LPTENUM\Yoyodyne_IndustriesDemoPrinter_F84F

rem Now uninstall the test driver and certificate.
devcon remove driver\demoprinter.inf LPTENUM\Yoyodyne_IndustriesDemoPrinter_F84F

certutil -delstore Root Demo_CA

4
如果要将其用于对驱动程序进行签名,则需要将CA证书导入到计算机存储中。我的示例将其导入到用户存储中,这对于大多数软件来说都可以用于测试/内部目的。
罗杰·利普斯科姆

20

在Powershell中使用New-SelfSignedCertificate命令非常容易。打开powershell并运行这3个命令。

1)创建证书
$ cert = New-SelfSignedCertificate -DnsName www.yourwebsite.com -Type CodeSigning -CertStoreLocation Cert:\ CurrentUser \ My

2)设置密码
$ CertPassword = ConvertTo-SecureString -String“ my_passowrd” -Force –AsPlainText

3)导出
Export-PfxCertificate-证书“ cert:\ CurrentUser \ My \ $($ cert.Thumbprint)” -FilePath“ d:\ selfsigncert.pfx”-密码$ CertPassword

您的证书selfsigncert.pfx将位于@D:/


可选步骤:您还需要将证书密码添加到系统环境变量中。为此,请在cmd中输入以下内容:setx CSC_KEY_PASSWORD "my_password"


JerryGoyal您知道如何将自签名证书转换为CA Root可信证书吗?
Heelis先生

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.