我有相同的症状,但完全是不同的原因。正如许多开发人员所做的那样,我的系统上安装了一堆不同的工具链。我只是对他们进行了调查,以展示这看起来如何;滚动到此答案的底部以查看完整列表。
我已经像往常一样在提升的命令提示符下使用 certutil -importPFX cert.pfx 将我的代码签名证书从 VeriSign 安装到系统证书存储(需要 /sm 和 signtool.exe)。
第一次测试看起来很有希望,但突然签名开始失败。
为了调试问题,我首先使用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.
我可以排除丢失的私钥,因为证书存储清楚地表明我有一个匹配的私钥:
现在我记得有 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 不会公开此行为,尽管从同一文件夹执行 signtool.exe。
我对此的最佳猜测是,由于 PATH 变量或类似变量搞砸了,signtool.exe 最终选择了错误的 DLL。值得注意的是 mssign32.dll 和 wintrust.dll 在 Windows SDK 8.0 和 8.1 的同一文件夹中伴随 signtool.exe,但不适用于任何早期版本的 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