Skip to content

MS_ASPNETCoreDataProtection

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

ASP.NET Coreのデータ保護

概要

  • ASP.NET Coreのデータ保護インフラストラクチャについて説明する。
  • 始めのウチはナンノコッチャ?だったが、

補足(「ナンノコッチャ」の解消): 原文の到達点(machineKey の後継)は
正確である。整理すると次の通り。

【ASP.NET (System.Web)】
   machine.config / web.config の <machineKey>
     → Forms 認証 Cookie、ViewState、__RequestVerificationToken を
       暗号化・署名するための鍵を、人が設定ファイルに書いていた
     → 複数台なら全台で同じ値にする(手作業)

【ASP.NET Core】
   Data Protection API(DPAPI とは別物)
     → 鍵の生成・保管・ローテーションをフレームワークが自動で行う
     → 既定では「アプリ 1 台限り」の鍵が自動生成される
     → 複数台なら「鍵の保管場所を共有する」設定を書く

何を守っているか(既定で暗号化される代表的なもの):

対象 用途
認証 Cookie ログイン状態(最重要)
セッション Cookie セッション ID
偽造防止トークン CSRF 対策(@Html.AntiForgeryToken()
TempData リダイレクト間のデータ受け渡し
パスワード リセット等のトークン ASP.NET Core Identity

鍵が揃っていないと何が起きるかが理解の要点である。

サーバ A が発行した Cookie を、サーバ B が復号できない
  → 「不正な Cookie」として破棄される
  → ログインが外れる/セッションが毎回新規になる
  → ログには CryptographicException / 警告が出る

複数台構成・コンテナ環境で最も踏みやすい落とし穴であり、
.NET CoreのDockerコンテナ化 でも同じ論点が出る。

詳細

AddDataProtection

  • IDataProtectionBuilder を返す。
  • サービス(認証、セッション、偽造防止)にデータ保護層を追加する。

補足(既定の鍵の保管場所): AddDataProtection()
呼ばなくてもデータ保護は動く(暗黙に有効)。
ただし鍵の保管場所が環境依存になる。

環境 既定の保管場所 問題
Windows(IIS 外) %LOCALAPPDATA%\ASP.NET\DataProtection-Keys プロセス ユーザー依存
IIS レジストリ(アプリ プール単位) アプリ プール再作成で失われる
Linux $HOME/.aspnet/DataProtection-Keys $HOME が無いと警告のみで揮発
コンテナ コンテナ内のファイル システム 再起動で消える

コンテナや複数台では、明示的に保管場所を指定するのが必須である。

SetApplicationName

アプリケーションの分離を行う。

補足(これを忘れると鍵を共有できない): 鍵は
アプリケーション名で分離される。既定のアプリ名は
コンテンツ ルート パスから導出されるため、

サーバ A: C:\inetpub\app1   → アプリ名が違う
サーバ B: /var/www/app1     → 鍵を共有していても復号できない
コンテナ: 毎回 ID が変わる  → 再起動のたびに別アプリ扱い

という事故が起きる。
保管場所を共有するなら、SetApplicationName も必ず揃える

builder.Services.AddDataProtection()
    .SetApplicationName("MyApp")     // ← 全台・全コンテナで同じ文字列
    .PersistKeysToFileSystem(new DirectoryInfo("/var/keys"));

PersistKeysTo* と ProtectKeysWith*

PersistKeysTo*

  • 有効な鍵と古い鍵を保存する鍵ストレージを設定する。
  • 各種、DataProtectionBuilderExtensions 中に以下のようなメソッドがある。
    • FileSystem
    • DbContext
    • AzureBlobStorage
    • StackExchangeRedis

ProtectKeysWith*

  • 鍵ストレージの鍵を使用して、鍵ストレージを保護する。
  • 各種、DataProtectionBuilderExtensions 中に以下のようなメソッドがある。
    • Certificate
    • AzureKeyVault

補足(2 段構えになっている理由): 名前が似ていて混乱しやすいが、
役割が違う

PersistKeysTo*   … 鍵束を「どこに置くか」(共有のため)
                     例: 共有フォルダ、Blob、Redis、DB

ProtectKeysWith* … その鍵束自体を「何で守るか」(保管場所が
                     平文で読めてしまうことへの対策)
                     例: 証明書、Key Vault、DPAPI
【鍵束(key ring)の中身】
   <key id="..." creation="..." activation="..." expiration="...">
     <descriptor>
       <encryption algorithm="AES_256_CBC" />
       <masterKey>...</masterKey>   ← ここが平文だと危険
     </descriptor>
   </key>

PersistKeysTo だけ設定して ProtectKeysWith を省くと
共有フォルダや Blob にマスター鍵が平文で置かれる
(Windows のローカル保存時は既定で DPAPI により保護されるが、
Linux・コンテナ・共有ストレージでは保護されない)。

選択の目安:

環境 PersistKeysTo ProtectKeysWith
Azure App Service(複数台) AzureBlobStorage AzureKeyVault
Kubernetes / コンテナ 永続ボリューム or Redis 証明書 or Key Vault
オンプレ複数台(Windows) 共有フォルダ(UNC) 証明書(DPAPI は使えない)
既に Redis がある StackExchangeRedis 証明書 / Key Vault
単一台・検証 既定のまま 不要

AddKeyManagementOptions

鍵に関するオプション設定を行う。

補足(主な設定項目): 既定の挙動を把握しておくと、
「なぜ突然ログインが外れたのか」を追いやすい。

オプション 既定 意味
NewKeyLifetime 90 日 鍵の有効期間(自動でローテーションされる)
AutoGenerateKeys true 期限が近づくと自動生成
AuthenticatedEncryptorConfiguration AES-256-CBC + HMACSHA256 アルゴリズム
builder.Services.AddDataProtection()
    .SetApplicationName("MyApp")
    .SetDefaultKeyLifetime(TimeSpan.FromDays(90))
    .PersistKeysToAzureBlobStorage(blobUri, credential)
    .ProtectKeysWithAzureKeyVault(keyUri, credential);

重要: 古い鍵は削除されず、復号のために保持され続ける
(ローテーションしても既存の Cookie は読める)。
逆に言えば、鍵束を消すと全ユーザーがログアウトする

補足(.NET Framework へ適用できるという記述について): 原文の
「本機構を .NET 4.5.1 以降に適用することも出来る」は正しい。
Microsoft.AspNetCore.DataProtectionnetstandard2.0 対応のため、
.NET Framework 版 ASP.NET からも参照できる。

ただし実務上の使いどころは限られ、

  • ASP.NET と ASP.NET Core を並行稼働させ、
    認証 Cookie を相互に読ませたい(段階的移行)

という場面が主である。
この用途には専用パッケージ
Microsoft.AspNetCore.DataProtection.SystemWeb が用意されており、
web.config に設定を入れることで
ASP.NET 側の暗号化を Data Protection API に置き換えることができる。
ASP.NET Coreへの移行
段階的に進める際の要素技術になる。

参考

実装例

mseeeen.msen.jp

Microsoft Learn


Tags: 移行, .NET開発, .NET Core, ASP.NET, ASP.NET MVC

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally