Code signing with signtool fails due to private key filter

后端 未结 5 1183
北荒
北荒 2021-02-05 06:35

While trying to sign some installer created by the company I am working for I encountered an error, which I have not been able to solve. I am using the same certificate which ha

相关标签:
5条回答
  • 2021-02-05 06:43

    I had same problem as mentioned. This is what I did - assuming you have setup the rest of the pre-requisites for code signing.

    1. Closed the solution and closed the VS IDE
    2. Launched the Visual Studio IDE with Run as Administrator privileges
    3. Open the solution and rebuild it

    This time the signing process was successful.

    I presume you have the right cert file and private key for signing and also imported the cert to the Trusted store.

    If not, you can continue to read more.

    1. Import the pfx file - "xyz.pfx" :: Open command prompt (launch - Run as Administrator privileges) and run the following command

      certutil.exe -p mypassword -importpfx xyz.pfx

      An output from the command is shown below as example:

      Certificate "CN=Name of the Cert, O=BLAH, OU=BLAH, E=john.doe@yourorg.com" added to store. CertUtil: -importPFX command completed successfully.

    2. Add the certificate to the Trusted Root Certification Authorities by using the following command. There are many ways to do but I used this. Open command prompt (launch - Run as Administrator privileges) and run the following command

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

      You will see an output message like this

      CertMgr Succeeded

    3. Sign the assembly. Simple process from Visual Studio IDE.

      • Right click the Project in your solution and open its properties.
      • Open Signing section and click on Sign the Assembly check box (Enable it)
      • Choose the pfx file using Browse option and enter the password
        you can also create a new one but you need a cert file that match to this pfx file, otherwise your signing will fail.
      • Save the changes
      • Now, Click on Build Events section and click Edit Post-Build to open the editor for post build events. Enter the following command.

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

        Path of the signtool.exe depends on where/whether you have installed the Windows SDK.

    Now build the solution, your solution should build successfully and your binaries signed. Ensure to run the VS IDE with Administrator privileges.

    0 讨论(0)
  • 2021-02-05 06:49

    I had the same symptom, but an altogether different cause. As many developers do, I have a bunch of different tool chains installed on my system. I just surveyed them to show how this can look; scroll to the bottom of this answer for the full list.

    I had installed my code-signing certificate from VeriSign to the system certificate store (requires /sm with signtool.exe) as usual, using certutil -importPFX cert.pfx from an elevated command prompt.

    First tests looked promising, but then suddenly the signing started to fail.

    To debug the issue I first started using signtool.exe sign /debug /v /a /sm ... in order to see what goes wrong. The output looked like this (also see question):

    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.
    

    I could rule out the missing private key, as the certificate store indicated clearly I have a matching private key:

    Property dialog for certificate

    Now I remember that there were some recent patches that allow Windows 7 to accept signatures made with a certificate that has a SHA256 hash. Although, of course, most older articles will state that Windows 7 cannot handle SHA-2 hashes at all.

    So this already gave me a nudge into the direction of "it's got to be an old version of something involved in signing".

    I still decided to remove the certificate plus key and reimport it using the invocation shown before.

    Then, after surveying my system (see at the bottom of the answer), I found a whopping five different versions of signtool.exe. So I started by trying the newest one (6.3.9600.17298, from the Windows 8.1 SDK) and it worked immediately:

    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
    

    Tracking this down further I thought I had found the issue. However, it turned out that the error I got is not what I would have gotten to see with the older signtool.exe versions. Instead older versions would have complained about /ac, /fd and /ph being unrecognized command line options, respectively.

    So I needed to dig a little deeper and it turned out that my (alternative) file manager was the culprit. I usually start my command prompts in the respective folder using that file manager and a handy keyboard shortcut. It turns out that it sometimes does not pass the environment variables - essentially the file manager "forgets" the environment variables. This turned out to be the root cause. A command prompt opened using Win+R and then cmd Enter would not expose this behavior despite executing signtool.exe from the same folder.

    My best guess from this is that due to a messed up PATH variable or similar, signtool.exe ended up picking the wrong DLL. Notably mssign32.dll and wintrust.dll accompany signtool.exe in the same folder for the Windows SDK 8.0 and 8.1, but not for any of the earlier versions of signtool.exe which will pick the "global" system-wide DLLs, whatever they turn out to be.


    On my system I had five different versions of signtool.exe.

    signtool.exe 5.2.3790.1830

    Doesn't even understand the /ac and /ph arguments I was using (also not /fd). But strangely enough worked without those two arguments.

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

    signtool.exe 6.0.4002.0

    Doesn't even understand the /ac and /ph arguments I was using (also not /fd). But strangely enough worked without those two arguments.

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

    signtool.exe 6.1.7600.16385

    First version to understand /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
    0 讨论(0)
  • 2021-02-05 06:49

    I also had to sign a file, using a certificate which I received from another source (similar to you). For me, the issue was that I only installed the certificate on my PC with the "Current User" option. Once I installed it, using the "Local Machine" option, it worked.

    0 讨论(0)
  • 2021-02-05 06:55

    I had the same issue on Win7 machine and tried everything that good people suggested in this post with no luck. Then, even my machine has only one account and it has admin privileges, I opened command prompt window by "Run as administrator" and then all versions of signtool.exe that I have installed start working.

    0 讨论(0)
  • 2021-02-05 07:04

    In order to sign a file you need to have the certificate's private key, which is not included in the *.cer file you copied from the Windows 7 machine. To export the certificate with its private key you can follow the instructions supplied here.

    Do note that you'll only be able to export the private key if the certificate was set to allow exporting it when it was created (by passing -pe to makecert)

    0 讨论(0)
提交回复
热议问题