接続文字列とその他の構成情報を保護する (C#)

作成者: Scott Mitchell

PDF のダウンロード

ASP.NET アプリケーションは、通常、Web.config ファイルに構成情報を格納します。 この情報の一部は機密性が高く、保護を保証します。 既定では、このファイルは Web サイトの訪問者には提供されませんが、管理者またはハッカーが Web サーバーのファイル システムにアクセスし、ファイルの内容を表示する場合があります。 このチュートリアルでは、ASP.NET 2.0 を使用すると、Web.config ファイルのセクションを暗号化して機密情報を保護できます。

はじめに

ASP.NET アプリケーションの構成情報は、一般的に という名前 Web.configの XML ファイルに格納されます。 これらのチュートリアルの過程で、いくつかの時間を Web.config 更新しました。 たとえば、最初のNorthwindチュートリアルで型指定された DataSet を作成すると、接続文字列情報は セクションの に<connectionStrings>自動的にWeb.config追加されました。 後で、マスター ページとサイト ナビゲーションのチュートリアルで、 を手動で更新Web.configし、プロジェクト内のすべての ASP.NET ページでテーマを使用する必要があることを示す要素をDataWebControls追加<pages>しました。

接続文字列などの機密データが含まれている可能性があるため Web.config 、 の内容を安全に保ち、未承認の Web.config 閲覧者から非表示にすることが重要です。 既定では、拡張子を持つ .config ファイルに対する HTTP 要求は、ASP.NET エンジンによって処理されます。 この種類のページは 、図 1 に示すメッセージを提供しません。 つまり、訪問者はブラウザーのアドレス バーに入力http://www.YourServer.com/Web.configするだけでは、ファイルの内容を表示Web.configできません。

ブラウザーから Web.config にアクセスすると、この種類のページが返されます。メッセージは提供されません

図 1: ブラウザーから Web.config アクセスすると、この種類のページが返されます。メッセージは表示されません (フルサイズの画像を表示する 場合はクリックします)

しかし、攻撃者がファイルの内容を表示 Web.config できる他の悪用を見つけた場合はどうでしょうか。 攻撃者はこの情報に対して何を行う可能性があり、 内 Web.configの機密情報をさらに保護するためにどのような手順を実行できますか? 幸いなことに、 のほとんどのセクションには Web.config 機密情報が含まれていません。 ASP.NET ページで使用されている既定のテーマの名前がわかっている場合、攻撃者はどのような害を及ぼす可能性がありますか?

ただし、特定 Web.config のセクションには、接続文字列、ユーザー名、パスワード、サーバー名、暗号化キーなどの機密情報が含まれています。 この情報は、通常、次 Web.config のセクションで確認できます。

  • <appSettings>
  • <connectionStrings>
  • <identity>
  • <sessionState>

このチュートリアルでは、このような機密性の高い構成情報を保護するための手法について説明します。 ご覧のように、.NET Framework バージョン 2.0 には、選択した構成セクションをプログラムで暗号化および復号化する保護された構成システムが含まれています。

注意

このチュートリアルでは、ASP.NET アプリケーションからデータベースに接続するための Microsoft の推奨事項について説明します。 接続文字列の暗号化に加えて、セキュリティで保護された方法でデータベースに接続していることを確認することで、システムのセキュリティ強化に役立ちます。

手順 1: ASP.NET 2.0 s の保護された構成オプションの確認

ASP.NET 2.0 には、構成情報を暗号化および復号化するための保護された構成システムが含まれています。 これには、構成情報をプログラムで暗号化または復号化するために使用できる.NET Frameworkのメソッドが含まれます。 保護された構成システムでは、プロバイダー モデルを使用します。これにより、開発者は、使用される暗号化実装を選択できます。

.NET Frameworkには、次の 2 つの保護された構成プロバイダーが付属しています。

保護された構成システムはプロバイダー設計パターンを実装するため、独自の保護された構成プロバイダーを作成してアプリケーションにプラグインすることができます。 このプロセスの詳細については、「 保護された構成プロバイダーの実装 」を参照してください。

RSA プロバイダーと DPAPI プロバイダーは、暗号化および暗号化解除ルーチンにキーを使用します。これらのキーは、マシン レベルまたはユーザー レベルで格納できます。 マシン レベルのキーは、Web アプリケーションが専用サーバー上で実行されるシナリオや、暗号化された情報を共有する必要がある複数のアプリケーションがサーバー上にある場合に最適です。 ユーザー レベルのキーは、同じサーバー上の他のアプリケーションがアプリケーションの保護された構成セクションを復号化できないようにする共有ホスティング環境では、より安全なオプションです。

このチュートリアルでは、DPAPI プロバイダーとマシン レベルのキーを使用する例を示します。 具体的には、 のWeb.configセクションの<connectionStrings>暗号化について説明しますが、保護された構成システムを使用してほとんどのWeb.configセクションを暗号化できます。 ユーザー レベルのキーの使用または RSA プロバイダーの使用については、このチュートリアルの最後にある「その他の読み取り」セクションのリソースを参照してください。

注意

RSAProtectedConfigurationProviderプロバイダーと DPAPIProtectedConfigurationProvider プロバイダーはそれぞれ、プロバイダー名RsaProtectedConfigurationProviderDataProtectionConfigurationProviderを使用してファイルに登録されますmachine.config。 構成情報を暗号化または暗号化解除する場合は、実際の型名 ( と DPAPIProtectedConfigurationProvider) ではなく、適切なプロバイダー名 (RsaProtectedConfigurationProviderRSAProtectedConfigurationProvider または DataProtectionConfigurationProvider) を指定する必要があります。 フォルダー内の machine.config ファイルを $WINDOWS$\Microsoft.NET\Framework\version\CONFIG 見つけることができます。

手順 2: 構成セクションのプログラムによる暗号化と暗号化解除

数行のコードを使用すると、指定したプロバイダーを使用して特定の構成セクションを暗号化または暗号化解除できます。 このコードは、簡単に説明しますが、プログラムで適切な構成セクションを参照し、その または UnprotectSection メソッドをProtectSection呼び出してから、 メソッドをSave呼び出して変更を保持する必要があります。 さらに、.NET Frameworkには、構成情報を暗号化および復号化できる便利なコマンド ライン ユーティリティが含まれています。 このコマンド ライン ユーティリティは、手順 3 で確認します。

構成情報をプログラムで保護する方法を説明するために、 で セクションWeb.configを暗号化および暗号化解除するためのボタンを含む ASP.NET ページを<connectionStrings>作成しましょう。

まず、フォルダー内の EncryptingConfigSections.aspx ページを AdvancedDAL 開きます。 ツールボックスから Designerに TextBox コントロールをドラッグし、そのプロパティを ID に、そのTextModeプロパティを WebConfigContentsMultiLine、プロパティWidthRowsをそれぞれ 95% と 15 に設定します。 この TextBox コントロールには、 の Web.config 内容が表示され、コンテンツが暗号化されているかどうかをすぐに確認できます。 もちろん、実際のアプリケーションでは、 の Web.config内容を表示する必要はありません。

TextBox の下に、 と DecryptConnStringsという名前EncryptConnStringsの 2 つの Button コントロールを追加します。 [テキスト] プロパティを [接続文字列の暗号化] と [接続文字列の暗号化解除] に設定します。

この時点で、画面は図 2 のようになります。

新しい TextBox コントロールと 2 つのボタン コントロールがあるEncryptingConfigSections.aspx ページが開かれた Visual Studio を示すスクリーンショット。

図 2: TextBox コントロールと 2 つのボタン Web コントロールをページに追加する (クリックするとフルサイズの画像が表示されます)

次に、ページが最初に読み込まれるときに TextBox に の Web.config 内容を WebConfigContents 読み込んで表示するコードを記述する必要があります。 次のコードをページの分離コード クラスに追加します。 このコードは、 という名前DisplayWebConfigのメソッドを追加し、 が falseの場合Page.IsPostBackPage_Loadイベント ハンドラーから呼び出します。

protected void Page_Load(object sender, EventArgs e)
{
    // On the first page visit, call DisplayWebConfig method
    if (!Page.IsPostBack)
        DisplayWebConfig();
}
private void DisplayWebConfig()
{
    // Reads in the contents of Web.config and displays them in the TextBox
    StreamReader webConfigStream = 
        File.OpenText(Path.Combine(Request.PhysicalApplicationPath, "Web.config"));
    string configContents = webConfigStream.ReadToEnd();
    webConfigStream.Close();
    WebConfigContents.Text = configContents;
}

メソッドではDisplayWebConfig、 クラスをFile使用してアプリケーションのWeb.configファイルを開き、StreamReaderクラスを使用してその内容を文字列に読み取り、クラスをPath使用してファイルへの物理パスをWeb.config生成します。 これら 3 つのクラスはすべて 名前空間にありますSystem.IO。 そのため、分離コード クラスの先頭に ステートメントを追加するか、またはこれらのクラス名の前に を付 usingSystem.IO ける System.IO. 必要があります。

次に、2 つの Button コントロール Click イベントのイベント ハンドラーを追加し、DPAPI プロバイダーでマシン レベルのキーを使用してセクションを暗号化および暗号化解除 <connectionStrings> するために必要なコードを追加する必要があります。 Designerから、各 Buttons をダブルクリックして分離コード クラスにイベント ハンドラーを追加Clickし、次のコードを追加します。

protected void EncryptConnStrings_Click(object sender, EventArgs e)
{
    // Get configuration information about Web.config
    Configuration config = 
        WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    // Let's work with the <connectionStrings> section
    ConfigurationSection connectionStrings = config.GetSection("connectionStrings");
    if (connectionStrings != null)
        // Only encrypt the section if it is not already protected
        if (!connectionStrings.SectionInformation.IsProtected)
        {
            // Encrypt the <connectionStrings> section using the 
            // DataProtectionConfigurationProvider provider
            connectionStrings.SectionInformation.ProtectSection(
                "DataProtectionConfigurationProvider");
            config.Save();
            
            // Refresh the Web.config display
            DisplayWebConfig();
        }
}
protected void DecryptConnStrings_Click(object sender, EventArgs e)
{
    // Get configuration information about Web.config
    Configuration config = 
        WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    // Let's work with the <connectionStrings> section
    ConfigurationSection connectionStrings = 
        config.GetSection("connectionStrings");
    if (connectionStrings != null)
        // Only decrypt the section if it is protected
        if (connectionStrings.SectionInformation.IsProtected)
        {
            // Decrypt the <connectionStrings> section
            connectionStrings.SectionInformation.UnprotectSection();
            config.Save();
            // Refresh the Web.config display
            DisplayWebConfig();
        }
}

2 つのイベント ハンドラーで使用されるコードはほぼ同じです。 どちらも、クラスの OpenWebConfiguration メソッドを使用して、現在のアプリケーションのWeb.configファイルに関する情報をWebConfigurationManager取得することから始めます。 このメソッドは、指定された仮想パスの Web 構成ファイルを返します。 次にWeb.config、ファイルの セクション<connectionStrings>には、 オブジェクトをConfiguration返す クラス s GetSection(sectionName) メソッドConfigurationSection使用してアクセスします。

オブジェクトにはConfigurationSection、構成セクションにSectionInformation関する追加情報と機能を提供する プロパティが含まれています。 上記のコードに示すように、プロパティの IsProtected プロパティを確認SectionInformationすることで、構成セクションが暗号化されているかどうかを判断できます。 さらに、セクションは、 プロパティProtectSection(provider)UnprotectSection メソッドをSectionInformation使用して暗号化または復号化できます。

メソッドは ProtectSection(provider) 、暗号化時に使用する保護された構成プロバイダーの名前を指定する文字列を入力として受け取ります。 EncryptConnString Button のイベント ハンドラーで、DPAPI プロバイダーが使用されるように DataProtectionConfigurationProvider を ProtectSection(provider) メソッドに渡します。 メソッドは UnprotectSection 、構成セクションの暗号化に使用されたプロバイダーを決定できるため、入力パラメーターは必要ありません。

または メソッドをProtectSection(provider)呼び出した後、オブジェクトの Save メソッドConfiguration呼び出して変更を保持する必要があります。UnprotectSection 構成情報が暗号化または暗号化解除され、変更が保存されたら、 を呼び出 DisplayWebConfig して更新 Web.config された内容を TextBox コントロールに読み込みます。

上記のコードを入力したら、ブラウザーからページに EncryptingConfigSections.aspx アクセスしてテストします。 セクションの内容 Web.config をプレーンテキストで <connectionStrings> 表示するページが最初に表示されます (図 3 を参照)。

Web ブラウザーに読み込まれたEncryptingConfigSections.aspx ページを示すスクリーンショット。

図 3: TextBox コントロールと 2 つのボタン Web コントロールをページに追加する (クリックするとフルサイズの画像が表示されます)

[接続文字列の暗号化] ボタンをクリックします。 要求の検証が有効になっている場合、TextBox から WebConfigContents ポストバックされたマークアップによって が生成 HttpRequestValidationExceptionされ、メッセージが表示されます。クライアントから危険な Request.Form 値が検出された可能性があります。 ASP.NET 2.0 で既定で有効になっている要求検証では、エンコードされていない HTML を含むポストバックが禁止され、スクリプトインジェクション攻撃を防ぐのに役立ちます。 このチェックは、ページ レベルまたはアプリケーション レベルで無効にすることができます。 このページでオフにするには、 ディレクティブで @PageValidateRequestfalse設定します。 ディレクティブは @Page 、ページの宣言型マークアップの上部にあります。

<%@ Page ValidateRequest="False" ... %>

要求の検証、その目的、ページ レベルとアプリケーション レベルで無効にする方法、および HTML エンコード マークアップの方法の詳細については、「 Request Validation - Preventing Script Attacks」を参照してください。

ページの要求の検証を無効にした後、もう一度 [接続文字列の暗号化] ボタンをクリックしてみてください。 ポストバックでは、構成ファイルにアクセスし、DPAPI <connectionStrings> プロバイダーを使用してそのセクションが暗号化されます。 その後、TextBox が更新され、新しい Web.config コンテンツが表示されます。 図 4 に示すように、 <connectionStrings> 情報は暗号化されるようになりました。

[接続文字列の暗号化] ボタンをクリックすると、connectionString> セクションが<暗号化されます

図 4: [接続文字列の暗号化] ボタンをクリックするとセクションが <connectionString> 暗号化されます (クリックするとフルサイズの画像が表示されます)

私のコンピュータで生成された暗号化された <connectionStrings> セクションは次のとおりですが、 要素のコンテンツ <CipherData> の一部は簡潔にするために削除されています。

<connectionStrings 
    configProtectionProvider="DataProtectionConfigurationProvider">
  <EncryptedData>
    <CipherData>
      <CipherValue>AQAAANCMnd8BFdERjHoAwE/...zChw==</CipherValue>
    </CipherData>
  </EncryptedData>
</connectionStrings>

注意

要素は <connectionStrings> 、暗号化の実行に使用されるプロバイダーを指定します (DataProtectionConfigurationProvider)。 この情報は、[ 接続文字列の暗号化の UnprotectSection 解除] ボタンがクリックされたときに メソッドによって使用されます。

接続文字列情報にアクセスWeb.configすると、コードによって、SqlDataSource コントロールから、または型指定された DataSets の TableAdapters から自動生成されたコードによって、自動的に暗号化が解除されます。 つまり、暗号化された <connectionString> セクションの暗号化を解除するために、追加のコードやロジックを追加する必要はありません。 これを示すには、この時点で前のチュートリアルの 1 つ (「基本的なレポート」セクションの簡易表示チュートリアルなど) にアクセスしてください (~/BasicReporting/SimpleDisplay.aspx)。 図 5 に示すように、このチュートリアルは想定したとおりに動作し、暗号化された接続文字列情報が ASP.NET ページによって自動的に復号化されていることを示しています。

データ アクセス層は接続文字列情報を自動的に復号化します

図 5: データ アクセス層は接続文字列情報を自動的に復号化します (フルサイズの画像を表示する をクリックします)

セクションを <connectionStrings> プレーンテキスト表現に戻すには、[接続文字列の暗号化解除] ボタンをクリックします。 ポストバックでは、接続文字列がプレーンテキストで Web.config 表示されます。 この時点で、このページに初めてアクセスしたときに画面が表示されます (図 3 を参照)。

手順 3: aspnet_regiis.exe を使用した構成セクションの暗号化

.NET Frameworkには、 フォルダー内のさまざまなコマンド ライン ツールが$WINDOWS$\Microsoft.NET\Framework\version\含まれています。 たとえば、 SQL キャッシュ依存関係の使用 に関するチュートリアルでは、コマンド ライン ツールを aspnet_regsql.exe 使用して SQL キャッシュの依存関係に必要なインフラストラクチャを追加する方法について説明しました。 このフォルダーのもう 1 つの便利なコマンド ライン ツールは、 ASP.NET IIS 登録ツール (aspnet_regiis.exe) です。 その名前が示すように、ASP.NET IIS 登録ツールは主に、ASP.NET 2.0 アプリケーションを Microsoft のプロフェッショナル レベルの Web サーバー IIS に登録するために使用されます。 IIS 関連の機能に加えて、ASP.NET IIS 登録ツールを使用して、 で Web.config指定された構成セクションを暗号化または暗号化解除することもできます。

次のステートメントは、コマンド ライン ツールを使用して構成セクションを暗号化するために使用される一般的な構文を aspnet_regiis.exe 示しています。

aspnet_regiis.exe -pef section physical_directory -prov provider

section は暗号化する構成セクション (connectionStrings など) であり、 physical_directory は Web アプリケーションのルート ディレクトリへの完全な物理パスであり、 provider は使用する保護された構成プロバイダーの名前です (DataProtectionConfigurationProvider など)。 または、Web アプリケーションが IIS に登録されている場合は、次の構文を使用して物理パスの代わりに仮想パスを入力できます。

aspnet_regiis.exe -pe section -app virtual_directory -prov provider

aspnet_regiis.exe の例では、DPAPI プロバイダーと <connectionStrings> コンピューター レベルのキーを使用してセクションを暗号化します。

aspnet_regiis.exe -pef
"connectionStrings" "C:\Websites\ASPNET_Data_Tutorial_73_CS"
-prov "DataProtectionConfigurationProvider"

同様に、コマンド ライン ツールを aspnet_regiis.exe 使用して構成セクションの暗号化を解除できます。 スイッチを使用する代わりに、 -pef を使用 -pdf します (または の -pe代わりに を使用 -pdします)。 また、暗号化を解除するときにプロバイダー名は必要ありません。

aspnet_regiis.exe -pdf section physical_directory
  -- or --
aspnet_regiis.exe -pd section -app virtual_directory

注意

コンピューターに固有のキーを使用する DPAPI プロバイダーを使用しているため、Web ページの提供元と同じコンピューターから を実行 aspnet_regiis.exe する必要があります。 たとえば、ローカル開発マシンからこのコマンド ライン プログラムを実行し、暗号化された Web.config ファイルを運用サーバーにアップロードした場合、運用サーバーは、開発用コンピューターに固有のキーを使用して暗号化されているため、接続文字列情報の暗号化を解除できません。 RSA プロバイダーには、RSA キーを別のコンピューターにエクスポートできるため、この制限はありません。

データベース認証オプションについて

アプリケーションが Microsoft SQL Server データベースに対してクエリDELETEINSERTUPDATEを発行SELECTする前に、まずデータベースがリクエスタを識別する必要があります。 このプロセスは認証と呼ばれ、SQL Serverは 2 つの認証方法を提供します。

  • Windows 認証 - アプリケーションが実行されているプロセスは、データベースとの通信に使用されます。 Visual Studio 2005 s ASP.NET Development Server を介して ASP.NET アプリケーションを実行する場合、ASP.NET アプリケーションは現在ログオンしているユーザーの ID を前提としています。 Microsoft インターネット インフォメーション サーバー (IIS) 上の ASP.NET アプリケーションの場合、ASP.NET アプリケーションは通常、 または domainName``\NETWORK SERVICEの ID をdomainName``\MachineName前提としていますが、これはカスタマイズできます。
  • SQL 認証 - 認証の資格情報として、ユーザー ID とパスワードの値が指定されます。 SQL 認証では、ユーザー ID とパスワードが接続文字列で提供されます。

WINDOWS 認証は、SQL 認証よりもセキュリティが強化されるため、推奨されます。 Windows 認証では、接続文字列はユーザー名とパスワードから解放され、Web サーバーとデータベース サーバーが 2 つの異なるマシンに存在する場合、資格情報はプレーンテキストでネットワーク経由で送信されません。 ただし、SQL 認証では、認証資格情報は接続文字列でハードコーディングされ、Web サーバーからデータベース サーバーにプレーンテキストで送信されます。

これらのチュートリアルでは、Windows 認証を使用しています。 接続文字列を調べることで、使用されている認証モードを確認できます。 チュートリアルの接続文字列Web.configは次のとおりです。

Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True

Integrated Security=True で、ユーザー名とパスワードがない場合は、Windows 認証が使用されていることを示します。 一部の接続文字列では、Integrated Security=True ではなく Trusted Connection=Yes または Integrated Security=SSPI という用語が使用されますが、3 つすべてがWindows 認証の使用を示します。

次の例は、SQL 認証を使用する接続文字列を示しています。 $CREDENTIAL_PLACEHOLDER$ は、パスワード キーと値のペアのプレースホルダーです。 資格情報は、接続文字列内に埋め込まれています。

Server=serverName; Database=Northwind; uid=userID; $CREDENTIAL_PLACEHOLDER$

攻撃者がアプリケーションの Web.config ファイルを表示できるとします。 SQL 認証を使用してインターネット経由でアクセスできるデータベースに接続する場合、攻撃者はこの接続文字列を使用して、SQL Management Studio または独自の Web サイト上の ASP.NET ページからデータベースに接続できます。 この脅威を軽減するには、保護された構成システムを使用して接続文字列情報Web.configを暗号化します。

注意

SQL Serverで使用できるさまざまな種類の認証の詳細については、「セキュリティで保護された ASP.NET アプリケーションの構築: 認証、承認、およびセキュリティで保護された通信」を参照してください。 Windows と SQL の認証構文の違いを示すその他の接続文字列例については、「ConnectionStrings.com」を参照してください。

まとめ

既定では、ASP.NET アプリケーション内の拡張子を持つ .config ファイルにブラウザーからアクセスすることはできません。 これらの種類のファイルは、データベース接続文字列、ユーザー名、パスワードなどの機密情報を含んでいる可能性があるため、返されません。 .NET 2.0 の保護された構成システムは、指定された構成セクションを暗号化できるようにすることで、機密情報をさらに保護するのに役立ちます。 RSA アルゴリズムを使用する構成プロバイダーと Windows Data Protection API (DPAPI) を使用するプロバイダーの 2 つの組み込みの保護された構成プロバイダーがあります。

このチュートリアルでは、DPAPI プロバイダーを使用して構成設定を暗号化および暗号化解除する方法について説明しました。 これは、手順 2 で説明したように、プログラムと、 aspnet_regiis.exe 手順 3 で説明したコマンド ライン ツールの両方で実現できます。 ユーザー レベルのキーを使用する方法、または代わりに RSA プロバイダーを使用する方法の詳細については、「その他の読み取り」セクションのリソースを参照してください。

プログラミングに満足!

もっと読む

このチュートリアルで説明するトピックの詳細については、次のリソースを参照してください。

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、テレサ・マーフィーとランディ・シュミットでした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。