为什么只有以管理员身份运行时,signtool.exe才能找到证书?

9
我正在设置一台新的开发笔记本电脑,并安装了一个自签名的代码签名证书。我可以在当前用户的“个人证书”下的certmgr中看到它。
当我尝试从Visual Studio 2017的“开发人员命令提示符”构建时,会出现以下错误:
error : SignTool Error: No certificates were found that met all the given criteria. 在我的旧笔记本电脑上始终正常工作。我发现如果我以管理员身份启动后从命令提示符运行相同的构建,则signtool可以成功找到证书。
我们有3/4个同事在设置新笔记本电脑时遇到了这种情况。其中一个人没有问题,并且可以在不以管理员身份运行的情况下进行签名。在旧笔记本电脑上,我们从未必须以管理员身份运行。
我尝试了谷歌来查找可能的原因,因为我不知道以管理员身份运行与否是否会对此产生任何影响。但我没有找到任何有关此问题的参考资料。
如何在不以管理员身份运行时使用signtool.exe?
当不是以管理员身份运行时,似乎会在“私钥筛选器”步骤处过滤掉我期望选择的证书:
**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.12
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************

C:\>signtool sign /v /debug /ph  /i "<issuedby>"  /fd sha256 /td sha256 "C:\TestSign.dll"

The following certificates were considered:
    Issued to: Scott Langham
    Issued by: <issuedby>
    Expires:   Sun Sep 25 09:54:55 2022
    SHA1 hash: <a_hash>

    Issued to: Scott Langham
    Issued by: <issuedby_somethingelse>
    Expires:   Wed May 13 15:51:14 2020
    SHA1 hash: <b_hash>

After EKU filter, 1 certs were left.
After expiry filter, 1 certs were left.
After Issuer 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版本与让这个工具正常工作的同事所使用的版本相同(10.0.18362.1)。我还能够发现我们系统之间的其他任何差异。


看起来有人遇到了类似的问题。解决方法是以管理员身份运行。我希望能像过去一样不以管理员身份运行。https://dev59.com/lF4b5IYBdhLWcg3wxURi#56342401 - Scott Langham
你尝试过使用签名证书的SHA1指纹进行签名吗?(/sha1选项)。我发现这是最简单的方法。 - Simon Mourier
这意味着您的signtool.exe中的bool Certificate::HasPrivateKey()返回false,因为CryptAcquireCertificatePrivateKey失败了。首先要快速处理NCryptOpenKey失败。尝试打开存储私钥的文件时失败,因为在非管理员身份下运行时被拒绝访问。这很奇怪,因为它要求只读访问权限。需要在调试器下查看此失败。我无法重现此问题。 - RbMm
你写道:“这在我的旧笔记本上总是很好用。” 你的旧笔记本使用什么操作系统?你的新笔记本使用什么操作系统? - Aleksandar
@Aleksandar 旧笔记本是Win8.1,新的是Win10。但这也发生在我的同事身上,他们的旧笔记本是Win10,他们也得到了新的笔记本电脑。 - Scott Langham
5个回答

4
我今天遇到了这个问题,现在我知道如何通过命令行运行signtool.exe而不需要提升为管理员权限。
  • 运行“mmc”并添加“证书”插件
  • 选择正确的密钥存储位置
    • (我的存储在本地计算机上,所以我在此处选择“计算机帐户”)
  • 查找并选择证书
  • 右键单击证书,选择所有任务>管理私钥...

enter image description here

在“私钥权限”对话框中,添加您的用户帐户,然后授予自己“完全控制”权限。现在您可以使用普通命令提示符进行签名。

Managing Certificate Permissions

  • 注意:如果您使用构建机器,请针对执行构建的帐户执行上述步骤。

1
太好了!我的证书在“当前用户\个人”存储中,但我没有看到“管理私钥…”选项。但是,在将证书导出并导入到“本地计算机\个人”存储后,我可以访问该选项并调整权限。现在它对我有用了!非常感谢,这个问题一直在每天困扰着我! - Scott Langham

2

与@Baget所说的类似,我建议你将你的计算机证书与你的同事进行比较,他可以成功运行SignTool.exe命令而不需要提升令牌。下面是一段PowerShell代码,可以帮助你:

与@Baget所说的类似,我建议您将您的计算机证书与那些可以成功运行SignTool.exe命令而无需提升标记的同事进行比较。这里是一段PowerShell代码,可为您提供帮助:

get-childitem -Path Cert:\ | foreach-object ({
    $location = $_.Location
    foreach($store in $_.StoreNames.Keys) {         
        get-childitem -Path "Cert:\$location\$store" | foreach-object ({
            $thumb = $($_.ThumbPrint)
            $issuer = $($_.Issuer)

            if ($issuer -eq "CN=EXAMPLE, DC=EXAMPLE, DC=EXAMPLE, DC=EXAMPLE") {
                write-host "$location $store $issuer"
            }
        })
    }
})

请记住,如果您以普通用户身份运行和以管理员身份运行,则上述输出可能略有不同。
最后,您和您的同事是否拥有相同的UAC设置?

1

我发现自己和signtool遇到了类似的情况,它拒绝使用管理员用户工作,但实际上作为管理员可以工作。

在我的情况下,我实际上并没有将证书导入证书存储中,而是使用从firefox中导出的comodo证书的.pkcs12文件,因此这使得事情变得更加奇怪,因为存储中任何密钥的权限都没有涉及。

我尝试授予自己对一些服务器密钥的权限,但那没什么用。

我希望有人能找到解决这个问题的方法。

与此同时,我改用osslsigncode签名我的exe,这完美地解决了问题。

我从msys2 mingw64构建中提取了exe和依赖的dll,这里是所有内容的zip文件,如果有用的话,只需将其提取到一个目录中并将其放入PATH中即可。

http://cachemiss.com/files/osslsigncode.zip

如果您想从msys2安装中提取此程序,可以使用以下命令:

pacman --noconfirm -S mingw-w64-x86_64-osslsigncode
cd /mingw64/bin
mkdir ~/osslsigncode
cp osslsigncode.exe $(ldd osslsigncode.exe | sed -n 's,^.*\(/mingw64/[^ ]*\).*,\1,p' | sort -u) ~/osslsigncode/
cd
zip -9r osslsigncode.zip osslsigncode

我在Visual Studio中使用cmake构建,没有任何问题。


0
在Windows中有两个证书存储,用户存储和机器存储。您可能已将证书安装到本地计算机上,或者在以提升的用户身份运行时安装了它。

0

首先,如果您在使用Visual Studio时遇到此类错误,请查看项目属性中的签名选项卡。您将看到一个先前分配的签名(强程序集)

如果您在此处输入正确的密码:

如果您的环境与编写项目的环境相同,则可以跳过此错误。请参阅关于该错误的文章

导致此错误的原因是:

1- 使用证书文件签署强程序集时,Visual Studio需要一些功能。

使用Visual Studio项目设计器的签名页面进行ClickOnce清单签名和强名称程序集签名

您可以尝试使用此代码来确定

signtool sign /debug /f mypfxfile.pfx /p <password> (mydllexectuable).exe

2- 这些设置可能因机器而异,而且Windows默认情况下不会将这些设置写入环境设置中。检查配置路径

这部分只是一个深度注释!与您的问题无关,您应该将私有密钥库文件添加到请求头中,这些都是为此而做的。我最喜欢的步骤是在此创建证书文章


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接