「コード署名」をWindows10で行う - signtool.exe編

インターネット経由で配布するWindows用アプリが改ざんされていないか検証することのできる「コード署名」を付けます。

Windows上でコード署名を行うにはいくつか方法はありますが、今回はsigntool.exeを利用した方法を試してみます。

準備

コード署名証明書

これが無いと始まりません。最終的にp12形式のファイルを用意します。取得までの道のりは以下のページをご覧ください。正直めんどくさいですが99ドル/年で取得できます。 blog.katsubemakito.net

こんな苦労したくないという方は日本語でサポートしてもらえるセクティゴジャパンから2.1万円/年で取得することもできます。日本国内だと恐らくこれが一番お手軽価格だと思われます。

Windows10 SDK

コード署名を行うコマンド「signtool.exe」はWindows10 SDKに含まれます。以下のページからダウンロード、インストーラーの指示に従って入れてください。 developer.microsoft.com

インストーラーの指示そのままで入れると「C:\Program Files (x86)\Windows Kits\10\App Certification Kit」の下にsigntool.exeがいます。

上記のフォルダにパスを通します。タスクバーで「環境変数」などで検索、環境変数を編集するウィンドウを開きます。「Path」を選択した状態で「編集」ボタンをクリック、新しく開いたウィンドウで「新規」ボタンをクリックし先ほどのパスをコピペします。

DOS窓PowerShellを起動しsigntool /?などでコマンドが実行できれば成功です。

コード署名を行う

Windowsでのコード署名はSHA1とSHA256の2種類のアルゴリズムを指定することができますが、初期のWindows7以前の古いOSへ対応するといった特別な事情がなければSHA256でコード署名を行いますwww.atmarkit.co.jp

ここでは需要があるか謎ですがSHA1とSHA256の両方のやり方を試してみます。

SHA1署名を行う

signtoolでコード署名を行う際の書式は以下の通りです。PowerShellではバッククオート(`)でコマンドを途中で改行することができます)

PS C:\> signtool sign /fd sha1 `
          /t http://timestamp.digicert.com `
          /f (証明書の場所) `
          /p (証明書のパスワード) `
          /d "(アプリ名などのコメント)" `
          (署名するファイル)

実際にやってみます。

PS C:\> signtool sign /fd sha1 /t http://timestamp.digicert.com /f xxxxx.p12 /p password /d "MyApp" xxxxx.exe
Done Adding Additional Store
Successfully signed: xxxxx.exe

成功したファイルを右クリックしプロパティを開くと「デジタル署名」という項目が追加されているのがわかりますね。

SHA256署名を行う

sha1となっていた箇所をsha256に、オプション/t/trに変更します。

PS C:\> signtool sign /fd sha256 /tr http://timestamp.digicert.com /f xxxxx.p12 /p password /d "MyApp" xxxxx.exe

プロパティを開くとダイジェストアルゴリズムの項目がSHA256になっているのがわかりますね。

SHA1とSHA256署名を同時に行う

前述のコマンドを2回打つだけです。異なる点は2回目のコマンドには/asオプションを指定することで、署名を追加して保存するモードになります。

PS C:\> signtool sign /fd sha1 /t http://timestamp.digicert.com /f xxxxx.p12 /p password /d "MyApp" xxxxx.exe
PS C:\> signtool sign /as /fd sha256 /tr http://timestamp.digicert.com /f xxxxx.p12 /p password /d "MyApp" xxxxx.exe

こちらもプロパティを開くとダイジェストアルゴリズムの項目にSHA1とSHA256の2つの署名が付加されているのを確認できます。

その他

コード署名を確認する

プロパティを見ても良いのですが、PowerShellからもsigntool verifyコマンドでコード署名が正しく行われているか確認することができます。

PS C:\> signtool verify /pa xxxxx.exe
File: xxxxx.exe
Index  Algorithm  Timestamp
========================================
0      sha256     RFC3161

Successfully verified: xxxxx.exe

コード署名を削除

すでに付与したコード署名を削除する場合は以下のコマンドで一発です。

PS C:\> signtool remove /s xxxxx.exe
Successfully committed changes to the file: C:\xxxxx.exe
Number of errors: 0

Sectigo/Comodoのタイムスタンプサーバが安定しない

Comodoで証明書を取ったので、せっかくならSectigo/Comodoのタイムスタンプサーバを利用したいところですが、こちらの使い方が悪いのか以下のようなエラーを吐くことが頻繁にあります(´・ω・`)

Error information: "Error: SignerSign() failed." (-2146869243/0x80096005) SignTool Error: The specified timestamp server either could not be reached or returned an invalid response.

そのためここではMSのドキュメントに従いdigicertのタイムスタンプサーバをお借りしているというわけです。無念。

参考ページ