-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ASPNETCoreDataProtection
- ASP.NET Coreのデータ保護インフラストラクチャについて説明する。
- 始めのウチはナンノコッチャ?だったが、
- 要は、machine.config、machineKey の後継と言う事らしい。
- 本機構を、.NET 4.5.1 以降に適用することも出来るらしい。
補足(「ナンノコッチャ」の解消): 原文の到達点(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コンテナ化 でも同じ論点が出る。
- IDataProtectionBuilder を返す。
- サービス(認証、セッション、偽造防止)にデータ保護層を追加する。
補足(既定の鍵の保管場所):
AddDataProtection()を
呼ばなくてもデータ保護は動く(暗黙に有効)。
ただし鍵の保管場所が環境依存になる。
環境 既定の保管場所 問題 Windows(IIS 外) %LOCALAPPDATA%\ASP.NET\DataProtection-Keysプロセス ユーザー依存 IIS レジストリ(アプリ プール単位) アプリ プール再作成で失われる Linux $HOME/.aspnet/DataProtection-Keys$HOMEが無いと警告のみで揮発コンテナ コンテナ内のファイル システム 再起動で消える コンテナや複数台では、明示的に保管場所を指定するのが必須である。
アプリケーションの分離を行う。
補足(これを忘れると鍵を共有できない): 鍵は
アプリケーション名で分離される。既定のアプリ名は
コンテンツ ルート パスから導出されるため、サーバ A: C:\inetpub\app1 → アプリ名が違う サーバ B: /var/www/app1 → 鍵を共有していても復号できない コンテナ: 毎回 ID が変わる → 再起動のたびに別アプリ扱いという事故が起きる。
保管場所を共有するなら、SetApplicationNameも必ず揃える。builder.Services.AddDataProtection() .SetApplicationName("MyApp") // ← 全台・全コンテナで同じ文字列 .PersistKeysToFileSystem(new DirectoryInfo("/var/keys"));
- 有効な鍵と古い鍵を保存する鍵ストレージを設定する。
- 各種、DataProtectionBuilderExtensions 中に以下のようなメソッドがある。
- FileSystem
- DbContext
- AzureBlobStorage
- StackExchangeRedis
- 鍵ストレージの鍵を使用して、鍵ストレージを保護する。
- 各種、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 単一台・検証 既定のまま 不要
鍵に関するオプション設定を行う。
補足(主な設定項目): 既定の挙動を把握しておくと、
「なぜ突然ログインが外れたのか」を追いやすい。
オプション 既定 意味 NewKeyLifetime90 日 鍵の有効期間(自動でローテーションされる) AutoGenerateKeystrue期限が近づくと自動生成 AuthenticatedEncryptorConfigurationAES-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.DataProtectionはnetstandard2.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への移行 を
段階的に進める際の要素技術になる。
-
AWSでASP.NET Coreのデータプロテクションキーの保存先を考える。 | かるあのメモ on WordPress
-
How to distribute Data Protection keys with an ASP.NET Core web app | by Tiago Araújo | The Startup | Jun, 2020
https://medium.com/swlh/how-to-distribute-data-protection-keys-with-an-asp-net-core-web-app-8b2b5d52851b
- [ASP.NET Core] データ保護キーを Azure Blob ストレージに永続化して Azure Key Vault で暗号化する
- 概要編
https://mseeeen.msen.jp/persist-keys-with-to-azure-blob-storage-and-protect-with-key-vault-in-aspnet-core-1/ - Azure Blob ストレージ設定編
https://mseeeen.msen.jp/persist-keys-with-to-azure-blob-storage-and-protect-with-key-vault-in-aspnet-core-2/ - Azure Key Vault 設定編
https://mseeeen.msen.jp/persist-keys-with-to-azure-blob-storage-and-protect-with-key-vault-in-aspnet-core-3/
- 概要編
- ASP.NET Core のデータ保護
https://learn.microsoft.com/ja-jp/aspnet/core/security/data-protection/introduction - ASP.NET Core データ保護の構成
https://learn.microsoft.com/ja-jp/aspnet/core/security/data-protection/configuration/overview - ASP.NET Core のキー記憶域プロバイダー
https://learn.microsoft.com/ja-jp/aspnet/core/security/data-protection/implementation/key-storage-providers - ASP.NET Core の ASP.NET machineKey を置き換える
https://learn.microsoft.com/ja-jp/aspnet/core/security/data-protection/compatibility/replacing-machinekey - ホスティング環境でのデータ保護キーの永続化
https://learn.microsoft.com/ja-jp/aspnet/core/security/data-protection/configuration/overview#persistkeystofilesystem
Tags: 移行, .NET開発, .NET Core, ASP.NET, ASP.NET MVC
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。