web-dev-qa-db-ja.com

秘密鍵フィルターが原因で、signtoolを使用したコード署名が失敗する

私が働いている会社が作成したいくつかのインストーラーに署名しようとしたときに、解決できないエラーが発生しました。別のマシン(Win7)で使用されているものと同じ証明書を、同じインストーラーにほぼ同じ方法で正常に署名しています。とにかく、CruiseControl.netを実行しているWindows Server 2008で、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を省略しました。私が間違っていたり、足りないことはありますか?

19
Paul Kertscher

ファイルに署名するには、証明書の秘密鍵が必要です。これは、Windows 7マシンからコピーした* .cerファイルには含まれていません。秘密鍵を含む証明書をエクスポートするには、 ここに記載されている手順 に従います。

証明書が作成されたときにエクスポートを許可するように証明書が設定されている場合(-pemakecertに渡すことによって)のみ秘密鍵をエクスポートできることに注意してください

5
Adi Lester

同じ症状がありましたが、完全に別の原因でした。多くの開発者と同じように、私はさまざまなツールチェーンをシステムにインストールしています。これがどのように見えるかを示すために調査したところです。完全なリストについては、この回答の下部までスクロールしてください。

昇格したコマンドプロンプトから_/sm_を使用して、コード署名証明書をVeriSignからシステム証明書ストアにインストールしました(_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ハッシュをまったく処理できないと述べています。

したがって、これはすでに「署名に関係する何かの古いバージョンでなければならない」という方向へのナッジを私に与えました。

stillは、証明書とキーを削除し、前に示した呼び出しを使用して再インポートすることを決定しました。

次に、私のシステムを調査した後(回答の下部を参照)、_signtool.exe_のなんとfive異なるバージョンが見つかりました。そこで、私は最新のもの(Windows 8.1 SDKの6.3.9600.17298)を試すことから始め、すぐに機能しました

_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を選択します。


私のシステムでは、five種類の_signtool.exe_がありました。

signtool.exe 5.2.3790.1830

私が使用していた_/ac_と_/ph_の引数さえ理解していません(また、_/fd_ではありません)。しかし、奇妙なことに、これら2つの引数なしで十分に機能しました。

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

signtool.exe 6.0.4002.0

私が使用していた_/ac_と_/ph_の引数さえ理解していません(また、_/fd_ではありません)。しかし、奇妙なことに、これら2つの引数なしで十分に機能しました。

  • 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
16
0xC0000022L

上記と同じ問題がありました。これが私がやったことです-コード署名のための残りの前提条件をセットアップしたと仮定します。

  1. ソリューションを閉じ、VS IDEを閉じました
  2. Visual Studioを起動IDE管理者として実行権限で実行
  3. ソリューションを開いて再構築します

今回は署名プロセスが成功しました。

署名用の適切な証明書ファイルと秘密鍵があり、信頼できるストアに証明書をインポートしていると思います。

そうでない場合は、続きを読むことができます。

  1. Pfxファイルをインポート-"xyz.pfx" ::コマンドプロンプトを開き(起動-管理者権限で実行)、次のコマンドを実行します

    _certutil.exe -p mypassword -importpfx xyz.pfx_

    コマンドの出力を以下に例として示します。

    証明書「CN =証明書の名前、O = BLAH、OU = BLAH、E = john.doe @ yourorg.com」がストアに追加されました。 CertUtil:-importPFXコマンドが正常に完了しました。

  2. 次のコマンドを使用して、信頼されたルート証明機関に証明書を追加します。方法はたくさんありますが、私はこれを使用しました。コマンドプロンプトを開き(起動-管理者権限で実行)、次のコマンドを実行します

    _certmgr.exe -add -c mycertificate.cer -s -r localMachine root_

    このような出力メッセージが表示されます

    CertMgrが成功しました

  3. 議会に署名する。 Visual Studio IDEからの単純なプロセス。

    • ソリューションでプロジェクトを右クリックし、そのプロパティを開きます。
    • Signingセクションを開いて、Sign the Assemblyチェックボックスをクリックします(有効にします)。
    • [参照]オプションを使用してpfxファイルを選択し、パスワードを入力します
      新しいものを作成することもできますが、このpfxファイルに一致する証明書ファイルが必要です。そうしないと、署名が失敗します。
    • 変更を保存します
    • ビルドイベントセクションをクリックし、ポストビルドの編集をクリックして、ビルド後のイベントのエディターを開きます。次のコマンドを入力します。

      "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を実行してください。

1
Jabez

私はWin7マシンでも同じ問題を抱えており、この投稿で善良な人々が提案したすべてのことを運なしで試しました。次に、私のマシンにアカウントが1つしかなく、管理者特権がある場合でも、「管理者として実行」でコマンドプロンプトウィンドウを開き、インストールしたすべてのバージョンのsigntool.exeが機能し始めます。

1
Vadim Gorelik

また、別のソースから受け取った証明書を使用して、ファイルに署名する必要がありました(あなたと同様)。私にとっての問題は、証明書を自分のPCに「現在のユーザー」オプションでのみインストールしたことでした。 「ローカルマシン」オプションを使用してインストールすると、動作しました。

enter image description here

0
Noceo