Подписание кода с помощью signtool не выполняется из-за фильтра закрытого ключа

При попытке подписать какой-то установщик, созданный компанией, я работаю, я столкнулся с ошибкой, которую я не смог решить. Я использую тот же сертификат, который был использован на другой машине (Win7) успешно таким же образом, чтобы подписать один и тот же установщик. Во всяком случае, на нашей Windows Server 2008, на которой работает CruiseControl.net, я попытался подписать установщик с помощью файла 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. Есть ли что-то, что я делаю неправильно или не хватает?

Ответ 1

Чтобы подписать файл, вам нужно иметь закрытый ключ сертификата, который не включен в файл *.cer, который вы скопировали с машины Windows 7. Чтобы экспортировать сертификат с помощью его закрытого ключа, вы можете следовать инструкциям приведенным здесь.

Обратите внимание, что вы можете экспортировать только закрытый ключ, если сертификат был установлен, чтобы разрешить экспортировать его, когда он был создан (путем передачи -pe в makecert)

Ответ 2

У меня был тот же симптом, но в целом другая причина. Как и многие разработчики, у меня есть набор различных цепочек инструментов, установленных в моей системе. Я только что просмотрел их, чтобы показать, как это может выглядеть; прокрутите до конца этого ответа для полного списка.

Я установил свой сертификат подписи кода из VeriSign в хранилище системных сертификатов (требуется /sm с 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

Теперь я помню, что были некоторые недавние исправления, которые позволяют Windows 7 принимать подписи, сделанные с сертификатом, имеющим хэш SHA256. Хотя, конечно, в большинстве старых статей указывается, что Windows 7 вообще не может обрабатывать хэши SHA-2.

Итак, это уже подтолкнуло меня к тому, что "это была старая версия чего-то, участвующего в подписании".

Я все же решил удалить сертификат плюс ключ и reimport с помощью показанного выше вызова.

Затем, после просмотра моей системы (см. внизу ответа), я нашел огромные пять разных версий signtool.exe. Поэтому я начал с того, что попробовал самую новую версию (6.3.9600.17298, из SDK для Windows 8.1) и работал сразу:

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 сопровождают signtool.exe в той же папке для Windows SDK 8.0 и 8.1, но не для любой из ранних версий 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

Ответ 3

У меня была такая же проблема на машине Win7 и пробовал все, что хорошие люди предлагали на этом посту, не повезло. Тогда даже моя машина имеет только одну учетную запись и имеет права администратора, я открыл окно командной строки "Запуск от имени администратора", а затем все версии signtool.exe, которые я установил, начинают работать.

Ответ 4

У меня была такая же проблема, как упомянуто. Это то, что я сделал - при условии, что вы настроили остальные предварительные условия для подписи кода.

  1. Закрыл решение и закрыл VS IDE
  2. Запустил Visual Studio IDE с правами запуска от имени администратора.
  3. Откройте решение и восстановите его

На этот раз процесс подписания прошел успешно.

Я предполагаю, что у вас есть правильный файл сертификата и закрытый ключ для подписи, а также импортирован сертификат в хранилище Trusted.

Если нет, вы можете продолжить читать больше.

  1. Импортируйте файл pfx - "xyz.pfx" :: Открыть командную строку (запуск - Запуск от имени администратора) и выполните следующую команду

    certutil.exe -p mypassword -importpfx xyz.pfx

    Вывод команды показан ниже в качестве примера:

    Сертификат "CN = Имя Сертификата, O = BLAH, OU = BLAH, [email protected]" добавлен в магазин. CertUtil: команда -importpfx выполнена успешно.

  2. Добавьте сертификат в доверенные корневые центры сертификации с помощью следующей команды. Есть много способов сделать, но я использовал это. Откройте командную строку (запуск - Запуск от имени администратора) и выполните следующую команду

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

    Вы увидите выходное сообщение, подобное этому

    CertMgr успешно

  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.
    • Сохраните изменения
    • Теперь щелкните раздел " События сборки " и нажмите " Редактировать после сборки", чтобы открыть редактор событий после сборки. Введите следующую команду.

      "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 запущен с правами администратора.

Ответ 5

Мне также пришлось подписать файл, используя сертификат, который я получил из другого источника (похоже на вас). Для меня проблема заключалась в том, что я установил сертификат только на своем ПК с опцией "Текущий пользователь". Как только я установил его, используя параметр "Локальный компьютер", он работал.

введите описание изображения здесь