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

时间:2015-02-24 08:19:14

标签: windows certificate code-signing private-key signtool

在尝试签署由我工作的公司创建的某些安装程序时,我遇到了一个错误,我无法解决。我使用相同的证书,已成功使用另一台机器(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.

我尝试将证书安装到不同的证书库,尝试使用不同版本的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

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

5 个答案:

答案 0 :(得分:15)

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

我像往常一样使用/sm从提升的命令提示符将VeriSign的代码签名证书安装到系统证书存储区(需要signtool.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.

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

Property dialog for certificate

现在我记得有some recent patches允许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

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

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

我最好的猜测是,由于混乱的PATH变量或类似变量,signtool.exe最终选择了错误的DLL。值得注意的是mssign32.dllwintrust.dll 伴随signtool.exe在Windows SDK 8.0和8.1的同一文件夹中,但不适用于任何早期版本的{{1}这将选择“全局”系统范围的DLL,无论它们是什么。

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

signtool.exe 5.2.3790.1830

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

  • /fd

signtool.exe 6.0.4002.0

甚至不理解我使用的C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin\signtool.exe/ac参数(也不是/ph)。但奇怪的是,没有这两个论点就足够了。

  • /fd

signtool.exe 6.1.7600.16385

要了解C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\Bin\signtool.exe的第一个版本。

  • /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

signtool.exe 6.2.9200.20789

  • C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe
  • C:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe

signtool.exe 6.3.9600.17298

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

答案 1 :(得分:5)

为了对文件进行签名,您需要拥有证书的私钥,该私钥不包含在从Windows 7计算机复制的* .cer文件中。要使用其私钥导出证书,您可以按照instructions supplied here

请注意,如果证书设置为允许在创建证书时将其导出(通过将-pe传递给makecert),您将只能导出私钥

答案 2 :(得分:1)

我在Win7机器上遇到了同样的问题,并尝试了好人在这篇文章中建议的所有内容,但没有运气。然后,即使我的机器只有一个帐户,它有管理员权限,我打开命令提示符窗口&#34;以管理员身份运行&#34;然后我安装的所有signtool.exe版本都开始工作。

答案 3 :(得分:1)

我遇到了同样的问题。这就是我所做的-假设您已经设置了代码签名的其余先决条件。

  1. 关闭解决方案并关闭VS IDE
  2. 使用“以管理员身份运行”特权启动Visual Studio IDE
  3. 打开解决方案并重建它

这次签名过程成功了。

我假设您具有正确的证书文件和私钥以进行签名,并且还将证书导入了受信任的商店。

如果没有,您可以继续阅读更多内容。

  1. 导入pfx文件-“ xyz.pfx” ::打开命令提示符(启动-运行 (以管理员权限)并运行以下命令

    certutil.exe -p mypassword -importpfx xyz.pfx

    该命令的输出如下所示:

      

    添加了证书“ CN =证书名称,O = BLAH,OU = BLAH,E = john.doe @ yourorg.com”   商店。   CertUtil:-importPFX命令成功完成。

  2. 使用以下命令将证书添加到受信任的根证书颁发机构。有很多方法可以做,但是我使用了这个方法。打开命令提示符(启动-以管理员身份运行)并运行以下命令

    certmgr.exe -add -c mycertificate.cer -s -r localMachine root

    您将看到这样的输出消息

      

    证书经理成功

  3. 在程序集上签名。从Visual Studio IDE进行的简单过程。

    • 右键单击解决方案中的项目,然后打开其属性。
    • 打开签名部分,然后单击签署程序集复选框(启用)
    • 使用“浏览”选项选择pfx文件并输入密码
      you can also create a new one but you need a cert file that match to this pfx file, otherwise your signing will fail.
    • 保存更改
    • 现在,单击 Build Events 部分,然后单击 Edit Post-Build 以打开用于后期构建事件的编辑器。输入以下命令。

      "C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64\signtool.exe" sign /v /sm "$(TargetPath)"

        

      signtool.exe的路径取决于Windows SDK的安装位置。

现在构建解决方案,您的解决方案应该成功构建并且您的二进制文件已签名。确保以管理员权限运行VS IDE。

答案 4 :(得分:0)

我还必须使用我从其他来源(与您类似)收到的证书签署文件。对我来说,问题是我只在我的电脑上安装了“当前用户”选项。一旦我安装它,使用“本地机器”选项,它就可以工作。

enter image description here