「アタッシェケース」 カテゴリーの記事です。

Inno Setupでsigntool.exeを使ってコードサイニング証明をつける


Inno Setupとはフリーのカスタマイズ可能なインストーラー作成ツール

拙作のアタッシェケースでは、インストーラーとしてInno Setupを使用しています。フリーでありながら、さまざまなオプションによるカスタマイズが可能で、究極はPascalでスクリプトを書いて走らせることもできます。

その中で、できあがったインストーラーにコードサイニング証明書を付けるのは、バッチファイルなどで処理していますが、Inno Setup で作成したインストーラー内に含まれる「アンインストーラー」にも証明書を付けてやらねばなりません。


昔の Inno Setup では、インストーラーとして固められたバイナリから、無理くり抜き出してコードサイニング証明書を付加していたようですが、現在のバージョンではそのオプションがあり、容易に証明書を付けることができます。

バッチファイルからの signtool.exe は無理筋っぽくて、Inno Setup の IDE から登録するのが無難

ただし、Inno Setup で作成したインストーラー内の「アンインストーラー」に証明書を付けるには、Innno Setupの設定ファイル(*.iss)をバッチファイルから Inno Setup コンパイラ(ISCC.exe)に喰わせることで、証明書を付加することはできないようです。

そこも一箇所にまとめて自動化するには、Node.js のモジュールを入れれば、近いことができそうです。

node-innosetup-compiler
https://github.com/felicienfrancois/node-innosetup-compiler

おとなしくバッチファイルで処理する場合には、signtool.exe の引数込みのコマンドを Inno Setup の IDE 上から登録することで、処理することができるようになります。

IDE から signtool.exe の処理を追加する

登録するには、Inno Setup の IDE メニュー「Tools」→「Configure sign tools…」を選択します。

すると、Sign Tool を選択するためのウィンドウが出てきますので、「Add」を押して、Signtool.exe を登録していきましょう。

まず、登録する signtool.exe の内容を示す「変数名」を入力します。ここは、設定ファイル(*.iss)で必要になってきますが、分かりやすい適当な名前で良いでしょう。ここでは、仮に「MySignTool」という名前にしました。

名前を入力すると、続いてその内容を入力するウィンドウが表示されます。前のウィンドウと似てますので少し注意が必要です。

そこに、

$qC:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\signtool.exe$q sign /v /a /n $qMitsuhiro Hibara$q /t http://timestamp.comodoca.com/authenticode $f


といった感じに、signtool.exe のコマンドライン実行形式を丸ごと入力してOKボタンを押します。ここに書き込まれる、signtool.exe の書式などの扱いについては後述します。

リストに、MySignTool=$qC:\Program Files\Microsoft....と表示されていると思います。

ここで、「OK」ボタンを押せば、signtool.exe のコマンドライン実行形式は、先ほど名前を付けた「MySignTool」変数に入り、Inno Setup の設定ファイル(*.iss)で使うことができます。

次に、設定ファイル(*.iss)にある、「Setup」セクションに、以下の二つを追加します。

issSignedUninstaller=yes
SignTool=MySignTool

これで設定は完了です。

ちなみに、上で例として使われている Inno Setup の設定ファイルは、GitHubで見ることができます。

https://github.com/hibara/AttacheCase3/blob/master/installer/AttacheCase.iss

Inno Setup で使う signtool.exe コマンドオプションの書式

さて、Inno Setup の変数として登録した signtool.exe ですが、コマンドオプションなどの書式詳細は以下を参考にすると良いでしょう。

SignTool.exe (署名ツール) – Microsoft
https://docs.microsoft.com/ja-jp/dotnet/framework/tools/signtool-exe

あと、書式内で$qや、$fといった記号が用いられていますが、こちらは、Innno Setup のパラメーターオプションです。

ちなみに、ここで使われている、$q は、クォートを示し、$f は、Innno Setup が与えるファイルパスなどが入ります。

$qC:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\signtool.exe$q sign /v /a /n $qMitsuhiro Hibara$q /t http://timestamp.comodoca.com/authenticode $f

前述した signtool.exe のコマンドライン書式を振り返って観ましょう。コマンドオプション詳細については、以下のページにあります。

SignTool.exe (署名ツール) – Microsoft
https://docs.microsoft.com/ja-jp/dotnet/framework/tools/signtool-exe

ですが、ここで使われているオプションについては、補足しておきます。

  • /v コマンドライン処理いた歳に、コマンドが正常に実行したか、失敗したかにかかわらず、詳細出力と警告メッセージが表示されます。
  • /n コードサイニング証明書をつける人の名前(法人なら組織名を指定します。
    /n "Mitsuhiro Hibara"
  • /t タイム スタンプ サーバーの URL を指定します。これは、コードサイニング証明書を取得した場所によって指定がちがうため、入手先のヘルプページか何かを参考にされると良いでしょう。
  • /a 最適な署名証明書を自動的に選択します。もっとも有効期間が長い証明書が自動で選択されます。個人でアプリケーションを配布されている方などは、複数コードサイニング証明書を持っているとは思えませんし、一つで管理しているのなら開発環境のあるPC内にインストールして、このオプションを使うのが、もっとも簡単かと思います。

もしも複数のコードサイニング証明書を運用したいとき

もしも複数の証明書を運用したい場合は、Inno Setup の「Configure Sign Tools…」メニューから、複数の signtool.exe の書式を「変数」として登録できるので、ここで切り替えても良いでしょう。

なお、以下のように、直接、コードサイニング証明書ファイル(*.pfx)を指定してコードサイニングすることも可能です。

signtool.exe sign /f $qM:\cert\SectigoLimited.pfx$q /p $qpasswordpassword$q /n $qMitsuhiro Hibara$q /t http://timestamp.comodoca.com/authenticode $f

/f オプションで、pfxファイルへのパスを指定して、/pオプションで、その pfxファイルを作成した際に入力いたパスワード文字列を指定しても、アンインストーラーに署名をすることが可能になります。

Windows7 以降に対応する

拙作のアタッシェケースは、まだ XP, Vista などに対応しているため、タイムスタンプサーバーで使用されるダイジェストアルゴリズムは、セキュリティ的に脆弱性が指摘されている、SHA-1を使っておりますが、もし Wndiow7 以降のアプリケーションにコードサイニング証明書を付けるのなら、SHA-2(SHA-256)を使用する方が無難でしょう。

signtool.exe sign /a /fd SHA256 /v /tr http://timestamp.comodoca.com /td sha256 $f

以上です。


nuget-icon

.NET FrameworkでDLLファイル(国際化対応リソースを含む)をexeにマージする


前のバージョンまで、「アタッシェケース」ではインストールを行うと、以下のプログラムフォルダーには、本体と並んで、DLLファイルがいくつか並んでいました。

AttacheCase.exe
AtcSetup.exe
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
ja-JP\AttacheCase.resources.dll

このファイル構成は、あくまで開発者側の都合であって、ユーザーにとっては良く分からないでしょう。

実行ファイルを別の場所へ移動させて使いたいとき、このDLLファイルも同時に移動させなくてはいけないのか?と迷ったり、煩わしいと思ったりするかもしれません。

実際、付属DLLファイルによっては、実行ファイルのあるフォルダーに存在しないと、正常に動かないものもあり、ユーザーにとっては、ツールのポータビリティが低く、やや使いづらいのではないかと考えました。

一つの実行ファイルに、すべての付属ファイルをマージする

というわけで、章題。これを目標にしてみました。そこで考えられる方策をいつくかご紹介したいと思います。

ILMerge(ILRepack)

もっとも手軽で定番なのは、「ILMerge」でしょうか。

Microsoft謹製のツールです。リンク先にあるツールをダウンロードしてインストールすると、使えるようになります。いろいろなオプションがあって、それに従って設定すれば、指定の実行ファイルにDLLファイルをマージできるようになります。

コマンドの例としては、以下のような感じです。

"C:\Program Files\Microsoft\ILMerge\ILMerge" /log:ilmerge.log /ndebug /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /out:AttacheCaseTemp.exe AttacheCase.exe Microsoft.WindowsAPICodePack.dll Microsoft.WindowsAPICodePack.Shell.dll ja-JP\AttacheCase.resources.dll

ところが、これですと、言語ファイルである、ja-JP\AttacheCase.resources.dllが残ってしまいます。どうやら、国際化対応リソースのDLLは「サテライトアセンブリ」といって、マージのときに除外されるみたいです。

ちなみに「ILMerge」は、Microsoftのプロプライエタリなツールですが、これをオープンソースにして、機能を拡張したものも存在します。「ILRepack」です。

これも、ILMergeと基本的に使い方は同じです。たとえば、以下のようにします。

"..\tools\ILRepack.exe" /log:ILRepack.log /ndebug /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /out:"C:\Users\mhibara\Desktop\AttacheCase.exe" AttacheCase.exe Microsoft.WindowsAPICodePack.dll Microsoft.WindowsAPICodePack.Shell.dll ja-JP\AttacheCase.resources.dll

ただ、これも、肝心の言語ファイルがマージされません。

NuGet

では、より簡単で、すべてのDLLファイルを実行ファイル(exe)にマージできないか調べて見ると、Visual Studio 2012以降では標準で付属しているツールの「NuGet」で、あるパッケージ群をインストールすれば可能になるようです。

まず、NuGetとは何か? マイクロソフト公式のウェブサイトにも説明はありますが、以下のウィキペディアの説明の方が簡潔ですので、そちらを参照なさってください。

NuGet
https://ja.m.wikipedia.org/wiki/NuGet

NuGetは、基本的にVS全体にインストールするというよりも、プロジェクト毎にインストールするようになっています。ですので、以下の画面では、「アタッシェケース」のソリューション(その中に各プロジェクト)が開いている状態で、NuGetパッケージ管理画面を開こうとしています。

 

Fody

次に「参照」から「fody」を検索して、Fodyを見つけたら、NuGetからパッケージを必要とするプロジェクトにチェックを入れ、そこへ「インストール」します。

Fodyとは以下のサイトにも説明がある通り、「Extensible tool for weaving .net assemblies(.NET Frameworkにアセンブリを組み込むための拡張ツール)」です。

Fody
https://github.com/Fody/Fody/

ただ、これだけではまだ不完全です。さらに、次にあるFodyのアドインをインストールする必要があります。

Fody.Costura

再びNuGetで「Fody Costura」を検索してインストールします。

Costuraとは、プロジェクトで使うリソースをアプリケーション本体に埋め込むためのツールです。

Costura is an add-in for Fody
https://github.com/Fody/Costura/

しかし、インストールしただけでは正常に動作しません。その後に、設定ファイルを所定の場所に置かなくてはなりません。ファイル名は以下の通り、決まっています。

FodyWeavers.xml

というファイルを作り、プロジェクトファイルがあるディレクトリに配置しなくてはなりません。

そのXMLファイルの中身ですが、最低限の設定であれば、以下の内容だけでO.K.です。ちなみに、公式GitHubのウェブサイトを見れば、埋め込みを除外するDLLを指定することができたり、様々なオプションが用意されているので、カスタマイズする場合はそちらを参考になさってください。なお、XMLファイルの文字エンコーディングはUTF-8なのでご注意を。



  

これにより、
Microsoft.WindowsAPICodePack.dll
Microsoft.WindowsAPICodePack.Shell.dll
の二つが「AttacheCase.exe」埋め込まれて、以下のようにファイルが出力されるかと思います。

 

Resource.Embedder

しかし、これでも、まだ国際化対応リソース(言語ファイル)DLL、
ja-JP\AttacheCase.resources.dll が統合されておりません。

そこで、もう一つNuGetパッケージをインストールします。「Resource.Embedder」です。

Resource.Embedder
https://github.com/MarcStan/Resource.Embedder

インストールは、以下の通りです。

これにより、ビルドを行うと、すべてのDLLリソースが「AttacheCase.exe」に埋め込まれて、以下のように単一で出力されます。

 

ただし、.NET Framework 4.0 だと古いバージョンを使う

Fody パッケージ自体は、.NET Frameworkのバージョン依存関係はありませんが、Fodyのプラグインである Costura の最新版の方には、

.NET Framework 4.6
Fody (>= 3.2.6)

といった依存関係があります。

ですので、アタッシェケースは、一応WindowsXP上でも動作するように、.NET Frameworkは、“4.0” でビルドするという縛りを設けているため

Fody ver.2.5.0
Costura.Fody ver.1.6.2

と、あえて古いバージョンのパッケージをそれぞれ使っています。

以上です。

「アタッシェケース#3」を正式版としました。


β版リリース時にもブログ記事を書きましたが、バグ報告もなくなり、自身で使っていても、目立った不具合がなくなってきたため、正式版としました。それでも細かいバグはまだまだありそうですので、もし何かあれば報告をいただけるとうれしいです。

アタッシェケース#3アイコンhttps://hibara.org/software/attachecase/

前述の記事でも書きましたが、Ver.2からの変更点のおさらい。

  • ファイルフォーマットの変更(Ver.3独自)
  • パスワードの扱いについての改良(RFC2898によるキー派生)
  • 暗号化、復号の処理速度の向上
  • Windows 10(タッチ操作など)に対応
  • パスワード付きZIPファイルの作成機能(おまけ)

ver.2は、2004年の開発開始からほとんど修正されることのなかったファイルフォーマットに手を入れました。冗長な部分を削除し、やや弱かったパスワード部分の扱いを改良、メモリで扱う部分を大きくし、また高速化(並列処理)に適したフォーマットにしました。

ですので、Ver.3で暗号化されたファイルは、Ver.2では復号できませんので、あらかじめご注意ください。ただし、Ver.2ファイルはVer.3では開けます。つまり上位互換です。

パスワード付きZIPファイルへの対応はおまけです(笑)。知人からの要望を受けて、入れてみました。邪魔で不評なら将来的に削除、好評なら復号処理も入れようかと思います。

技術的な変更点は、

  • .NET Frameworkでの開発
  • コードサイニング証明書の付加

今までC++Builderで開発を行ってきましたが、毎年のバージョンアップ費用がもはや個人ユースとして耐えられなくなってきたのと、無料で使える、Microsoftの「Microsoft Visual Studio Express 2015 for Windows Desktop」にした方が、より多くの人にとって、オープンソースからのプルリクエストや、フォークがしやすいのではないかと思い、乗り換えてみました。

また、暗号化ツールという性質上、セキュリティ面での使用を躊躇してしまうのを少しでも軽減しようと、コードサイニング証明書を付加してみました。法人ではなく僕個人のもので、けっこうなお値段でしたが、少しでも安心して使っていただけるようにと自腹で負担しました(泣)。

より多くの人に使っていただけるのが、開発者としては望外の喜びです。

電卓の16進から10進へ

C#で文字列をバイナリサーチする



前提として、僕のケースでは、『アタッシェケース#3』にて、ファイル先頭から固定値である「_AttacheCaseData」(16バイト)を検索していきます。それにより、自己実行形式ファイルのデータ境界が分かるようになります。

ウェブを検索してみたら、以下のサイトが近い感じがするのですが、

バイナリデータを検索する方法(vb.net)
http://www.my-hobby.jp/index.php/2012/01/vb-net2/

File.ReadAllBytes()で、一気にファイルをバイト単位での読み込みを行っています。僕のアタッシェケース#3では、出力されるファイルが、2GBを余裕で超えてくるファイルも扱う可能性もあるので、それは使えません。

そこで、File.ReadByte()を使います。知ってましたか、ReadByte();

// _AttacheCaseData
//byte[] AtcTokenByte = { 0x5F, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x43, 0x61, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61};
int[] AtcTokenByte = { 95, 65, 116, 116, 97, 99, 104, 101, 67, 97, 115, 101, 68, 97, 116, 97};

using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
{
  bool fToken = false;
  int b;
  while ((b = fs.ReadByte()) > -1)
  {
    //-----------------------------------
    // Check the token "_AttacheCaseData"
    if (b == AtcTokenByte[0])
    {
      fToken = true;
      for ( int i = 1; i < AtcTokenByte.Length; i++)
      {
        if (fs.ReadByte() != AtcTokenByte[i])
        {
          fToken = false;
          break;
        }
      }
      if ( fToken == true)
      {
        _fExecutableType = true;
        break;
      }
    }

  }// end while();

}

ReadByte()は、ストリームから1バイトずつ読み込んで行きます。ただし、返値がバイトではなく、Int32 にキャストされた符号なしバイト(int)で返ってくるのに要注意。

あらかじめ分かっている定数ならば、僕のようにint配列にしますが、場合によっては、byte値をその度にintにキャストして比較しても良いでしょう。

電卓の16進から10進へ

ちなみにbyte値をintにするには、Windowsの電卓を「プログラマ」にして「16進」→数値入力→「10進」にして、値を出しました。16進を10進に脳内変換で出来ちゃうプログラマーさんはすごいと思う(常識デスカ?)。

「アタッシェケース#3」をリリースしました



「アタッシェケース#3」のβテスト版をリリースしました。ようするにアタッシェケースの「Version.3」へのメジャーバージョンアップです。

アタッシェケース#3アイコンhttps://hibara.org/software/attachecase/   

僕が好んで使っていた統合開発環境「C++Builder」の価格高騰に伴いバージョンアップを諦め、無料で使える、Microsoftの「Microsoft Visual Studio Express 2015 for Windows Desktop」に乗り換えて、開発しました。言語は、C#ですので、ほぼフルスクラッチでの開発でした。

2004/07/25 に『ver.2』がリリースされてから、ここまで少しずつ改良を重ねてきましたが、 それはほとんどが本体側だけで、そこから生成される暗号化データの形式は、互換性を保つため、 ほぼ当時のままの設計で来ていました。

あれから年月が経つにつれて、当時の僕の拙いプログラミングから、パスワードの扱い方にやや弱い部分があることや、 暗号化するバッファの一部がとても小さく、暗号化・復号処理に時間がかかっていたことなどが分かって来ました。

また、データに格納するファイル情報が冗長になり、不要なもの、次第に使われなくなったものが多くなってきました。 そこで今回のメジャーバージョンをキッカケにして、データの仕様も全面的に見直し、再設計を行いました。 その結果、Ver.3 は、Ver.2よりも暗号強度の高いファイルを生成します。

そのため、暗号化ファイルは上位互換です。Ver.3で暗号化したファイルは、ver.2では開くことはできません。ただし、Ver.3では、Ver.2のファイルは開くことができます。

ソースコードは、GPLv3ライセンスとして、GitHubにもアップロードされています。ご興味のある方はぜひご覧いただき、フィードバックや改良案などいただけると嬉しいです(ただし、簡単な質問はググってね♥)。

また今回から、Windows 10にも正式対応しました。一応、タッチパネルを意識した作りをしたつもりですが、細かいところではどうでしょうか。タッチパネルを頻繁に使われる方で、この辺りの挙動でご不便なところがあれば、ご意見いただきたいです。

s