デジタル署名環境をクラウドに移行した話

この記事は弥生 Advent Calendar 2024 シリーズ1の9日目の記事です。

弥生の石橋です。開発本部でデスクトップ製品共通モジュールのエンジニアを担当しています。
Windowsアプリケーション開発者であれば避けては通れないデジタル署名。
先年、CA/ブラウザフォーラムにおけるコードサイニング基本要件の変更が行われ、弥生で利用しているDigiCertの証明書の要件が変更となりました。

[重要]コードサイニング証明書における要件変更について(2022年11月)

この影響を受け、デジタル署名環境を変更する必要があったのですが、弥生ではAzureを利用したデジタル署名環境を採用しました。
この記事では、採用までに至った経緯や、Azureの環境構築からアプリケーションの署名方法まで紹介します。

デジタル署名環境の要件変更

これまではDigiCertから入手した証明書をデジタル署名用マシンにインストールして、MicrosoftのSignToolを利用して署名を行っていました。
しかしながら、上記の要件変更に伴い、コードサイニング証明書の秘密鍵はFIPS140 Level2、 Common Criteria EAL 4+、または同等のセキュリティ要件を満たすハードウェアに格納されなければならないこととなり、一般的なマシンに直接に保管することはできなくなりました。
これに伴って、DigiCertへの証明書の申請の手順も変更になり、下記のいずれかの方法を選択して申請することとなりました。

  1. DigiCertが提供するハードウェアトークンを利用する
  2. 自分でハードウェアトークンを準備する
  3. HSM(Hardware Security Module)を利用する

弥生の対応

弥生では仮想環境でデジタル署名を付与しており、デジタル署名プロセスはCI/CDで自動化されています。
これに対し、1と2のハードウェアトークンを利用する方法は下記理由から採用が難しいものでした。

  • ハードウェアトークンが仮想環境で利用できないため、物理マシンを用意する必要がある
  • SignToolでデジタル署名を付与する際に都度パスワードの入力が必要である

そのため、3のHSMを利用する方法を検討しました。
しかし、物理的なHSMデバイスやクラウドHSMは非常に高価で、デジタル署名の秘密鍵だけを保管する用途としてはコストに見合っていませんでした。
そんな中、AzureのKey VaultというサービスがオプションとしてHSMを利用できるため、上述の要件を満たして証明書と秘密鍵を保管できることがわかりました。
また、AzureSignToolというツールを用いることでKey Vaultに保管された証明書を用いてWindowsアプリケーションに署名できることもわかりました。
Key Vaultは月額5USD+0.03USD/10,000トランザクション(弥生で利用している鍵長の場合)と安価に利用することができ、Azure自体は弥生で利用していて導入にハードルもなかったため、Key Vault+AzureSignToolでデジタル署名を行う事としました。

Azureの環境構築

1. キーコンテナーの作成

まずはキーコンテナーを作成します。
この際、価格レベルはプレミアムを選択します。
プレミアムとすることで、上述のハードウェア要件を満たす秘密鍵を作成できるようになります。

2. キーコンテナーのアクセス制御(IAM)の設定

キーコンテナーのアクセス制御(IAM)ロールの割り当ての追加からキーコンテナー管理者を自身のアカウントに設定します。
以降の操作のため必要となります。

3. 証明書の作成

証明書生成/インポートし、証明書を作成します。
ポリシーの詳細構成で下記を入力または選択します。

項目
証明機関 (CA) の種類 統合されていない CA によって発行された証明書
拡張キー使用法 (EKU) 1.3.6.1.5.5.7.3.3
X.509 キーの使用フラグ デジタル署名
エクスポート可能な秘密キーですか? いいえ
キーの種類 RSA-HSM

他の項目はプロジェクトに応じて設定してください。

証明書が作成出来たら、作成された証明書を開き、証明書の操作CSRのダウンロードをクリックすることでCSRがダウンロードできます。

4. 証明書のマージ

先の手順でダウンロードしたCSRをDigiCert等の認証局に送付すると、証明書を取得することができます。
Key Vaultで作成した証明書を選択し、署名された要求をマージをクリックして、認証局から取得した証明書をマージします。

5. アプリの登録

後述のAzureSignToolからこれまでの手順で登録した証明書を利用するために、Microsoft Entra IDからアプリを登録する必要があります。
まず、アプリの登録の新規登録から、新しいアプリを作成します。
作成したアプリの証明書とシークレットから、新しいクライアントシークレットを作成します。
作成したシークレットの値は画面を遷移するとコピーできなくなるため、作成後の画面で保存しておいてください。

6. アクセス権限の付与

手順5で作成したアプリにKey Vaultの証明書を利用するための権限を与えます。 作成したキーコンテナーのアクセス制御 (IAM)ロールの割り当ての追加より、下記の2つの職務ロールを作成したアプリに割り当てます。

  • Key Vault Certificate User
  • キー コンテナー暗号化ユーザー

7. 認証情報の取得

手順5で取得したシークレットの他に、AzureSignToolで下記の情報が必要となるので取得します。

  • 手順1で作成したキーコンテナー
    • コンテナーのURI
  • 手順3で作成した証明書
    • 証明書の名前
  • 手順5で作成したアプリ
    • アプリケーション (クライアント) ID
    • ディレクトリ (テナント) ID

これでAzureの環境構築は完了です!
必要に応じてキーコンテナーのネットワークの設定からファイアウォールの設定を行ってください。

デジタル署名

AzureSignToolのインストール

.NETがインストールされている環境であれば、dotnetコマンドでインストールすることができます。

dotnet tool install --global AzureSignTool

.NETがインストールされていない場合、.NETをインストールして上記コマンドを実行するか、GitHubのReleaseからアセットを取得してください。
Releaseに公開されているアセットは.NETのインストールなく利用することができます。

AzureSignToolによる署名

先述の手順で取得した情報を利用して、下記コマンドを実行することでデジタル署名を付与することができます。

AzureSignTool sign ^
    -kvt <テナントID> ^
    -kvu <コンテナーのURI> ^
    -kvi <アプリケーションID> ^
    -kvs <シークレット> ^
    -kvc <証明書の名前> ^
    -t <タイムスタンプサーバーのURL(例:http://timestamp.digicert.com)> ^
    -v <署名対象のファイルパス>

最後のファイルパスは複数指定することも可能です。
複数のファイルをまとめてAzureSignToolに渡すと、1回の証明書へのアクセスで複数のファイルへのデジタル署名ができ、高速かつ低コストなのでおススメです。
ファイルパスが長くなる場合はテキストファイルでファイルパスのリストを作成しておき、-iflオプションで指定することもできます。

AzureSignTool sign ^
    -kvt <テナントID> ^
    -kvu <コンテナーのURI> ^
    -kvi <アプリケーションID> ^
    -kvs <シークレット> ^
    -kvc <証明書の名前> ^
    -t <タイムスタンプサーバーのURL(例:http://timestamp.digicert.com)> ^
    -ifl <署名対象のファイルリストが記載されたテキストファイルのパス>

おわりに

今回の記事では、Azure Key VaultとAzureSignToolを用いたデジタル署名環境の構築方法について紹介しました。
秘密鍵の保管要件が厳しくなったことで、秘密鍵が漏洩してデジタル署名のなりすましが発生するというリスクも低減されるので、今回の要件変更で対応できてよかったと思っています。

本記事が、デジタル署名環境の構築に役立つ情報となれば幸いです。
弥生 Advent Calendar 2024では、今後も様々な技術情報を発信していきますので、ぜひご期待ください。



弥生では一緒に働く仲間を募集しています。
開発生産性を追求しているチームにご興味のある方、ぜひエントリーお待ちしております。
herp.careers