我们有一个传统的Windows工作流程流程,使用SignerSign
将数字签名应用于EXE。我们正在远离Windows Workflow流程,因此我一直在新流程的上下文中准备一个工具来执行相同的签名操作。我将代码签名代码从Workflow Activity复制/粘贴到新项目中的类中,但是当我尝试运行它时遇到错误。
代码的大致概述是:
CertOpenStore
用于打开包含私钥和证书的PFX文件。CertEnumCertificatesInStore
来获取证书上下文。SignerSign
,SIGNER_SUBJECT_INFO
指向目标EXE文件,SIGNER_CERT
指向上一步的证书上下文,SIGNATURE_SIGNER_INFO
指定SHA应该使用-1算法。 (我尝试将算法更改为SHA-2 512,但结果没有变化。)pProviderInfo
参数为NULL
。SignerTimeStamp
以对签名应用时间戳。代码中的注释表示如果使用pwszHttpTimeStamp
SignerSign
参数,则返回HRESULT 0x80070020(“正在使用的文件”?)当我尝试在Windows 10 64位上运行此代码时,无论是从32位还是64位进程,我都会收到错误HRESULT 0x80092006“没有为商店或对象指定提供程序。”。我尝试提供pProviderInfo
,将提供程序名称设置为“Microsoft Strong Cryptographic Provider”(在SignTool.exe签署可执行文件的API监视器跟踪输出中看到 - 这有效),但它不会影响结果。
有谁知道这个错误究竟意味着什么,以及如何解决它?
答案 0 :(得分:0)
我完全不知道为什么会这样,但是通过按摩我的代码就可以看到SignTool在Rohitab的API监视器中执行的操作,然后将其丢弃到看似最小的工作集,现在这个再次签署文件:
CertOpenStore
。 PFXImportCertStore
用于打开PFX文件并生成HCERTSTORE
。这需要将PFX加载到内存中,以便它可以作为CRYPT_DATA_BLOB
传递 - 没什么大不了的。CertEnumCertificatesInStore
获取证书上下文。CertGetCertificateChain
用于生成的证书上下文,其中包含不受限制的CERT_CHAIN_PARA
和标记CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING | CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
。没有指定其他商店。当我最初写这篇文章时,基于API监视器的结果,我定义CERT_CHAIN_PARA_HAS_EXTRA_FIELDS
并按照API Monitor捕获显示的方式填充它们,但我继续从S_OK
获取SignerSign
短CERT_CHAIN_PARA
结构。SignerSign
,除了作为嵌套在hCertStore
内的SIGNER_CERT_STORE_INFO
结构的SIGNER_CERT
传入虚拟集合类型存储。通过调用CertOpenStore
两次创建此虚拟集合类型存储,一次使用CERT_STORE_PROV_COLLECTION
并标记CERT_STORE_CREATE_NEW_FLAG
,一次使用CERT_STORE_PROV_MEMORY
指定编码PKCS_7_ASN_ENCODING | X509_ASN_ENCODING
,然后添加使用CertAddStoreToCollection
将内存存储到集合存储区。如果未指定虚拟集合类型存储,则SignerSign
会抱怨它无法找到受信任根的路径。请注意,我在测试中使用的证书是自签名的,因此没有到受信任根的路径。也许虚拟集合类型存储对于具有到受信任根的路径的代码签名证书是不必要的,我目前没有办法测试。
无论如何,我希望这有助于解决可能遇到SignerSign
问题的其他人的问题。 : - )