由于私钥过滤器,使用signtool进行代码签名失败

Pau*_*her 16 windows code-signing certificate signtool private-key

在尝试签署由我工作的公司创建的一些安装程序时,我遇到了一个错误,我无法解决.我使用相同的证书,已成功使用另一台机器(Win7)以相同的方式签署准相同的安装程序.无论如何,在运行CruiseControl.net的Windows Server 2008上,我尝试使用signtool.exe对安装程序进行签名,但它失败并出现以下错误:

The following certificates were considered:
    Issued to: <our company>
    Issued by: <some ca>
    Expires:   <is valid>
    SHA1 hash: <...>

    Issued to: <...>
    Issued by: <...>
    Expires:   <...>
    SHA1 hash: <...>

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
After Subject Name filter, 1 certs were left.
After Private Key filter, 0 certs were left.
SignTool Error: No certificates were found that met all the given criteria.
Run Code Online (Sandbox Code Playgroud)

我尝试将证书安装到不同的证书库,尝试使用不同版本的signtool.exe并尝试直接使用.cer文件,但没有区别.我在所有情况下都收到了上述错误.我尝试了以下命令行命令

signtool.exe sign /debug /n "MyCompany" C:\my\installer.exe
signtool.exe sign /debug /f C:\path\to\my\certificate.cer C:\my\installer.exe
Run Code Online (Sandbox Code Playgroud)

但是在某些情况下我离开了/ debug.我有什么不对或错过的吗?

0xC*_*22L 16

我有相同的症状,但完全不同的原因.正如许多开发人员所做的那样,我的系统上安装了许多不同的工具链.我刚刚对它们进行了调查,以展示它的外观; 滚动到此答案的底部以获取完整列表.

我已经安装从VeriSign我的代码签名证书到系统证书存储(需要/smsigntool.exe)和往常一样,使用certutil -importPFX cert.pfx从提升的命令提示.

首次测试看起来很有希望,但随后突然签署开始失败.

要调试我首先开始使用的问题signtool.exe sign /debug /v /a /sm ...,以便查看出现了什么问题.输出看起来像这样(也见问题):

The following certificates were considered:
    Issued to: localhost
    Issued by: localhost
    Expires:   Tue Dec 26 00:00:00 2017
    SHA1 hash: <...>

    Issued to: <...>
    Issued by: Symantec Class 3 SHA256 Code Signing CA
    Expires:   <...>
    SHA1 hash: <...>

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
After Root Name filter, 1 certs were left.
After Private Key filter, 0 certs were left.
SignTool Error: No certificates were found that met all the given criteria.
Run Code Online (Sandbox Code Playgroud)

我可以排除丢失的私钥,因为证书存储区明确指出我有一个匹配的私钥:

证书的属性对话框

现在我记得有一些最近的补丁允许Windows 7接受使用具有SHA256哈希的证书进行的签名.当然,虽然大多数旧文章都会声明Windows 7根本无法处理SHA-2哈希值.

所以这已经让我对"它必须是签署中涉及的旧版本"的方向有所推动.

仍然决定删除证书加密钥并使用之前显示的调用重新导入它.

然后,在调查我的系统后(见答案的底部),我发现了五个不同版本的signtool.exe.所以我开始尝试最新版本(6.3.9600.17298,来自Windows 8.1 SDK),它立即起作用:

signtool.exe sign /debug /v /a /sm /r VeriSign /ac MSCV-VSClass3.cer /ph  /t "http://timestamp.verisign.com/scripts/timstamp.dll" *.exe

The following certificates were considered:
    Issued to: localhost
    Issued by: localhost
    Expires:   Tue Dec 26 00:00:00 2017
    SHA1 hash: <...>

    Issued to: <...>
    Issued by: Symantec Class 3 SHA256 Code Signing CA
    Expires:   <...>
    SHA1 hash: <...>

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
After Root Name filter, 1 certs were left.
After Private Key filter, 1 certs were left.
The following certificate was selected:
    Issued to: <...>
    Issued by: Symantec Class 3 SHA256 Code Signing CA
    Expires:   <...>
    SHA1 hash: <...>

Cross certificate chain (using machine store):
    Issued to: Microsoft Code Verification Root
    Issued by: Microsoft Code Verification Root
    Expires:   Sat Nov 01 13:54:03 2025
    SHA1 hash: 8FBE4D070EF8AB1BCCAF2A9D5CCAE7282A2C66B3

        Issued to: VeriSign Class 3 Public Primary Certification Authority - G5
        Issued by: Microsoft Code Verification Root
        Expires:   Mon Feb 22 19:35:17 2021
        SHA1 hash: 57534CCC33914C41F70E2CBB2103A1DB18817D8B

            Issued to: Symantec Class 3 SHA256 Code Signing CA
            Issued by: VeriSign Class 3 Public Primary Certification Authority - G5
            Expires:   Sat Dec 09 23:59:59 2023
            SHA1 hash: 007790F6561DAD89B0BCD85585762495E358F8A5

                Issued to: <...>
                Issued by: Symantec Class 3 SHA256 Code Signing CA
                Expires:   <...>
                SHA1 hash: <...>


The following additional certificates will be attached:
    Issued to: VeriSign Class 3 Public Primary Certification Authority - G5
    Issued by: Microsoft Code Verification Root
    Expires:   Mon Feb 22 19:35:17 2021
    SHA1 hash: 57534CCC33914C41F70E2CBB2103A1DB18817D8B

    Issued to: Symantec Class 3 SHA256 Code Signing CA
    Issued by: VeriSign Class 3 Public Primary Certification Authority - G5
    Expires:   Sat Dec 09 23:59:59 2023
    SHA1 hash: 007790F6561DAD89B0BCD85585762495E358F8A5

Done Adding Additional Store
Successfully signed: <...>.exe

Number of files successfully Signed: 1
Number of warnings: 0
Number of errors: 0
Run Code Online (Sandbox Code Playgroud)

进一步跟踪这个我以为我找到了问题.然而,事实证明我得到的错误并不是我用旧signtool.exe版本看到的错误.相反,旧版本会抱怨/ac,/fd以及/ph未被识别的命令行选项,分别.

所以我需要深入挖掘一下,事实证明我的(替代)文件管理器是罪魁祸首.我通常使用该文件管理器和方便的键盘快捷方式在相应的文件夹中启动我的命令提示.事实证明,它有时不会传递环境变量 - 实质上是文件管理器"忘记"环境变量.结果证明这是根本原因.使用Win+ 打开命令提示符R,然后cmd Enter尽管signtool.exe从同一文件夹执行,也不会显示此行为.

我最好的猜测是,由于混乱的PATH变量或类似的变量,signtool.exe最终选择了错误的DLL.值得注意的是mssign32.dll,它wintrust.dll 伴随着signtool.exeWindows SDK 8.0和8.1的相同文件夹,但对于任何早期版本signtool.exe都不会选择"全局"系统范围的DLL,无论结果如何.


在我的系统上,我有五个不同的版本signtool.exe.

signtool.exe 5.2.3790.1830

甚至不理解/ac/ph论据我使用(也不能/fd).但奇怪的是,没有这两个论点就足够了.

  • C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin\signtool.exe

signtool.exe 6.0.4002.0

甚至不理解/ac/ph论据我使用(也不能/fd).但奇怪的是,没有这两个论点就足够了.

  • C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\Bin\signtool.exe

signtool.exe 6.1.7600.16385

首先要了解的版本/fd sha256.

  • C:\WINDDK\7600.16385.1\bin\amd64\SignTool.exe
  • C:\WINDDK\7600.16385.1\bin\x86\SignTool.exe
  • C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe
  • C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\signtool.exe
  • C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe

signtool.exe 6.2.9200.20789

  • C:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe
  • C:\Program Files (x86)\Windows Kits\8.0\bin\x86\signtool.exe

signtool.exe 6.3.9600.17298

  • C:\Program Files (x86)\Windows Kits\8.1\bin\arm\signtool.exe
  • C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe
  • C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe


Adi*_*ter 6

为了对文件签名,您需要具有证书的私钥,该私钥不包含在从Windows 7计算机复制的* .cer文件中。要导出带有私钥的证书,您可以按照此处提供说明进行操作

请注意,只有将证书设置为允许在创建证书时将其导出(通过传递-pemakecert),您才能导出私钥