22

証明書ファイルで実行する方法を説明しているサイトは多数あります。要約すると、次signtool.exeのようになります。.pfx

signtool.exe sign /f mycert.pfx /p mypassword /t http://timestamp.server.com \
  /d "My description"   file1.exe file2.exe

ほとんどの CI プロセスと同様に、すべてを実行する継続的インテグレーション CI プロセスのセットアップ (TeamCity を使用) があります。現在、同一の VM を実行している 3 つのビルド エージェントがあり、それらのどれでもこのプロセスを実行できます。

安全でない実装

今日これを達成するために、セキュリティに関する限り、いくつかの悪いこと (TM) を行います。.pfx ファイルはソース管理にあり、そのパスワードはビルド スクリプト (ソース管理にもあります) にあります。これは、ソース コード リポジトリにアクセスできるすべての開発者が、pfx ファイルを取得して、好きなように悪意のあることを実行できることを意味します。(私たちは比較的小さな開発ショップであり、誰もがアクセスできることを信頼していますが、明らかにこれはまだ良くありません)。

究極の安全な実装

これを「正しく」行うことについて私が見つけることができるのは、次のことだけです。

  • pfx とパスワードを安全な媒体 (指でロックを解除できる暗号化された USB ドライブなど) に保管し、おそらく一緒に保管しないでください。
  • 署名ファイルへのアクセス権を持つ人を数人だけ指定する
  • このコード署名セレモニーのために持ち出す必要があるまで、ロックアップされた保管庫に保管されている、接続されていない専用マシンでのみ最終ビルドに署名してください。

これのセキュリティのメリットはわかりますが..非常に重いプロセスであり、時間の面で費用がかかります(このプロセスを実行し、証明書のバックアップを安全に保持し、コード署名マシンが動作状態であることを確認するなど) )。

手順をスキップして、個人のシステムに保存されている証明書を使用してファイルに手動で署名するだけの人もいると思いますが、それでも素晴らしいことではありません。

また、インストーラー (ビルド サーバーによってビルドされる) 内で使用される署名ファイルとも互換性がありません。これは、管理者アクセスを取得するための UAC プロンプトを持つ .exe がインストールされている場合に重要です。

中盤?

私は、それが私の会社であることを証明することよりも、恐ろしい「信頼できないアプリケーション」UAC プロンプトをユーザーに提示しないことにはるかに関心があります。同時に、すべての開発者 (および QA と高度な技術サポート) がアクセスできるソース コード リポジトリに秘密キーとパスワードを格納することは、明らかに適切なセキュリティ プラクティスではありません。

私が望むのは、CI サーバーが現在のようにビルド プロセス中に署名することですが、パスワード (または証明書の秘密鍵部分) がなくても、ソース コード リポジトリにアクセスできるすべての人がアクセスできるようにすることです。

パスワードをビルドから保護したり、何らかの方法で保護したりする方法はありますか? signtool に証明書ストアを使用するように指示する必要がありますか (また、3 つのビルド エージェントとビルドを非対話型ユーザー アカウントとして実行する場合)。他の何か?

4

2 に答える 2

10

@GiulioVlan が提案したものと非常によく似たアプローチを行うことになりましたが、いくつかの変更があります。

MSBuild タスク

signtool.exe を実行する新しい MSBuild タスクを作成しました。このタスクは、いくつかの主な目的に役立ちます。

  • パスワードが表示されないようにします
  • 失敗時にタイムスタンプ サーバーに対して再試行できます。
  • 呼び出しやすくなります

ソース: https://gist.github.com/gregmac/4cfacea5aaf702365724

これは具体的にすべての出力を取得し、サニタイザー関数を介して実行し、パスワードをすべて * に置き換えます。

通常の MSBuild コマンドを検閲する方法を認識していないため、コマンドラインでパスワードを直接 signtool.exe に渡すと、それを使用してパスワードが表示されます。したがって、このタスクが必要になります (他の利点は別として)。

レジストリのパスワード

パスワードを「帯域外」に保存するいくつかの方法について議論し、最終的にレジストリを使用することに落ち着きました。MSBuild から簡単にアクセスでき、手動で管理するのもかなり簡単です。ユーザーがマシンへの RDP およびリモート レジストリ アクセスを持っていない場合でも、実際にはかなり安全です (別の言い方をする人はいますか?)。派手な GPO を使用してセキュリティを確保する方法もあると思われますが、それは私が行きたいと思っている長さを超えています。

これは、msbuild で簡単に読み取ることができます。

$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\1 Company Dev@CodeSigningCertPassword)

また、regedit を使用して簡単に管理できます。

ここに画像の説明を入力

なぜ他の場所ではないのですか?

  • ビルド スクリプト内: ソース コードを持っている人なら誰でも見ることができます
  • ソース管理で暗号化/難読化/非表示: 誰かがソースのコピーを取得した場合でも、これを理解することができます
  • 環境変数: Teamcity Web UI には、すべての環境変数とその値を実際に表示する各ビルド エージェントの詳細ページがあります。このページへのアクセスは制限できますが、他の機能も制限されることを意味します
  • ビルド サーバー上のファイル: 可能ですが、ファイル共有などを介して誤ってアクセス可能になっている可能性が少し高いようです

MSBuild からの呼び出し

タグ内:

<Import Project="signtool.msbuild.tasks"/>

(これを他のタスクと共通のファイルに入れるか、直接埋め込むこともできます)

次に、署名に使用するターゲットで次のようにします。

<SignTool  SignFiles="file1.exe;file2.exe" 
   PfxFile="cert.pfx" 
   PfxPassword="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\1 Company Dev@CodeSigningCertPassword)"
   TimestampServer="http://timestamp.comodoca.com/authenticode;http://timestamp.verisign.com/scripts/timstamp.dll" />

これまでのところ、これはうまく機能しています。

于 2014-12-12T01:59:07.237 に答える