共用方式為


使用加密來保護密碼

Saad Ladki

簡介

本檔概述為 IIS 7.0 和更新版本伺服器設定應用程式集區和背景工作進程隔離所需的步驟。 應用程式集區隔離需要保護 WAS(IIS 本機系統進程)需要存取的數據。 此數據的範例是應用程式集區密碼。 另一方面,背景工作進程隔離需要保護應用程式集區身分識別需要存取的數據。 此數據的範例是匿名用戶帳戶密碼。

先決條件

為了協助簡化此程式,會提供兩個範例程式代碼:

  • 在 machine.config中建立新的 RSA 加密提供者。
  • 在 machine.config中設定預設提供者的名稱。

最後的必要條件一節會引導您設定四個將在稍後主題中使用的用戶帳戶。

建立新的 RSA 加密提供者應用程式

  1. 開啟 Windows 記事本,並在您選擇的名為 createProvider.cs 目錄中建立檔案,其中包含下列 C# 程式代碼:

    using System;
    using Microsoft.Web.Administration;
    using System.Configuration;
    
    namespace testingEncryption
    {   
        public class createProvider   
        {
            public static void Main(string[] args)
            {
                String keyContainerName = args[0];
                String description = args[1];
                String providerName = args[2];
                System.Configuration.Configuration machineConfig =
                System.Configuration.ConfigurationManager.OpenMachineConfiguration();
                System.Configuration.ProviderSettings settings =
                    new System.Configuration.ProviderSettings(providerName,
                    "System.Configuration.RsaProtectedConfigurationProvider,
                    System.Configuration,
                    Version=2.0.0.0, Culture=neutral,
                    PublicKeyToken=b03f5f7f11d50a3a");
                settings.Parameters["description"] = description;
                settings.Parameters["keyContainerName"] = keyContainerName;
                settings.Parameters["cspProviderName"] = String.Empty;
                settings.Parameters["useMachineContainer"] = "true";
                settings.Parameters["useOAEP"] = "false";
                settings.Parameters["name"] = providerName;
                ProtectedConfigurationSection pcSection =
                    (System.Configuration.ProtectedConfigurationSection)machineConfig.GetSection ("configProtectedData");
                pcSection.Providers.Add(settings);
                machineConfig.Save();
            }
        }
    }
    
  2. 接下來,啟動提升權限的命令提示字元:

    • 按兩下 [ 開始] 選單。
    • 以滑鼠右鍵點選 命令提示字元。
    • 選取 [ 以系統管理員身分執行]。
  3. 在命令提示字元視窗中,流覽至您儲存 createProvider.cs 檔案的位置,然後執行下列命令來編譯程式代碼:
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\csc.exe /reference:%SystemRoot%\System32\inetsrv\Microsoft.Web.Administration.dll createProvider.cs

此步驟現已完成。

建立應用程式以變更預設提供者

  1. 開啟 Windows 記事本,並在您選擇的名為 setProvider.cs 的目錄中建立檔案,其中包含下列 C# 程式代碼:

    using System;
    using Microsoft.Web.Administration;
    using System.Configuration;
    namespace testingEncryption 
    {
        public class setProvider
        {
            public static void Main(string[] args)
            {
                String provider = args[0];  // example: DataProtectionConfigurationProvider
                System.Configuration.Configuration machineConfig =
                    System.Configuration.ConfigurationManager.OpenMachineConfiguration();
                ProtectedConfigurationSection pcSection =
                    (System.Configuration.ProtectedConfigurationSection)machineConfig.GetSection("configProtectedData");
                string oldEncryptionProviderName = pcSection.DefaultProvider;
                Console.WriteLine("The default provider is currently: " + oldEncryptionProviderName);
                Console.WriteLine("Changing the default provider to: " + provider);
                pcSection.DefaultProvider = provider;
                machineConfig.Save();
            }
        }
    }
    
  2. 接下來,啟動提升權限的命令提示字元:

    • 按兩下 [ 開始] 選單。
    • 以滑鼠右鍵點擊 [命令提示字元]。
    • 選取 [ 以系統管理員身分執行]。
  3. 在命令提示字元視窗中,流覽至您儲存 setProvider.cs 檔案的位置,然後執行下列命令來編譯程式代碼:
    %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\csc.exe /reference:%SystemRoot%\System32\inetsrv\Microsoft.Web.Administration.dll setProvider.cs

此步驟現已完成。

建立用戶帳戶

在此步驟中,我們會建立四個新的用戶帳戶,以在整個檔中使用。

若要開始,請使用下列步驟開啟以系統管理許可權執行的命令殼層視窗:

  1. 按兩下 [ 開始] 選單。
  2. 以滑鼠右鍵點選 命令提示字元
  3. 選取 [ 以系統管理員身分執行]。
  4. 在命令視窗中,執行下列命令:
net user /add AppPoolIdentity1 password1
   net user /add AppPoolIdentity2 password2
   net user /add AnonymousAccount1 password3
   net user /add AnonymousAccount2 password

此步驟現已完成。

應用程式集區隔離

IIS 有一個稱為 WAS 的進程,會在 LOCALSYSTEM 的內容下執行,而且是唯一需要存取應用程式集區密碼的程式。 在此工作中,我們會:

  • 建立名為 iisWasKey 的新 RSA 金鑰,只有 LOCALSYSTEM 和 Administrators 可以存取。 此金鑰將用來加密每個應用程式集區的密碼。
  • 建立兩個應用程式集區。
  • 設定每個應用程式集區,以在不同的身分識別下執行,並使用 iisWasKey 加密其密碼。
  • 限制密鑰檔案的 NTFS 檔案系統許可權,因此只有 SYSTEM 和系統管理員才能存取。

建立新的 RSA 金鑰

  1. 按兩下 [ 開始] 選單。
  2. 以滑鼠右鍵按下 命令提示字元。
  3. 選取 [ 以系統管理員身分執行]。
  4. 在命令視窗中,流覽至您儲存 createProvider.exe 的位置,然後執行下列命令:
createProvider.exe iisWasKey RsaKeyForWAS Rsa_WAS

確認這些變更已正確發生。 使用 Windows 記事本開啟 %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\config\machine.config,並確認新提供者的區段行是否存在:

<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
    <providers>
        <add name="RsaProtectedConfigurationProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" keyContainerName="NetFrameworkConfigurationKey" cspProviderName="" useMachineContainer="true" useOAEP="false"/>

        <add name="DataProtectionConfigurationProvider" type="System.Configuration.DpapiProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="Uses CryptProtectData and CryptUnProtectData Windows APIs to encrypt and decrypt" useMachineProtection="true" keyEntropy=""/>

        <add name="Rsa_WAS" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="RsaKeyForWAS" keyContainerName="iisWasKey" cspProviderName="" useMachineContainer="true" useOAEP="false" />
    </providers>
</configProtectedData>

加密應用程式集區密碼

根據預設,每當屬性加密時,IIS 都會使用 defaultProvider 進行 machine.config中所定義的加密。預設值為 RsaProtectedConfigurationProvider。

在此步驟中,我們會使用稍早建立的 setProvider.exe 應用程式,將提供者變更為 iisWasKey,然後使用 IIS 管理員來變更密碼:

  1. 按兩下 [ 開始] 選單。
  2. 以滑鼠右鍵按下 命令提示字元。
  3. 選取 [ 以系統管理員身分執行]。
  4. 在命令視窗中,流覽至您儲存 setProvider.exe 的位置,然後執行下列命令:
setProvider.exe Rsa_WAS

已成功變更預設提供者Rsa_WAS。

建立新的應用程式集區

在此步驟中,我們會建立兩個新的應用程式集區,以彼此隔離。 若要這樣做,請啟動 IIS 管理員:

  1. 按兩下 [開始],然後輸入 'INetMgr.exe',然後按 Enter 鍵(如果出現提示,請選取 [ 繼續 ] 以提升您的許可權)。

  2. +按兩下 [連線] 區段中您電腦名稱旁邊的按鈕。

  3. 按一下 [ 應用程式集區]。

  4. 選取右側名為 新增應用程式集區 的工作。

  5. 輸入名稱 'AppPool1',然後按 [確定 ],如下所示:

    [新增應用程式集區] 對話框的螢幕快照,其中將焦點放在 O K 選項上。

  6. 重複上述步驟,但這次會使用名稱 AppPool2

  7. 您現在會在 IIS 中看到下列畫面:
    [應用程式集區] 畫面的螢幕快照,其中顯示伺服器上的應用程式集區清單。

  8. 請注意 AppPool1AppPool2 的身分識別如何為 NetworkService。 我們將變更為稍早建立的帳戶,方法是以滑鼠右鍵按兩下 [AppPool1 ],然後選取 [ 進階設定]

  9. 在 [ 處理模型] 標題底下:

    • 按兩下 身分識別字右邊的按鈕。

    • [應用程式集區標識符 ] 視窗中,選取 [自定義帳戶] 單選按鈕,然後按兩下 [設定...]按鈕。

    • 在 [ 設定 認證] 對話框中輸入下列使用者名稱和密碼。

      用戶名稱: AppPoolIdentity1
      password: password1

      [設定認證] 對話框的螢幕快照,其中顯示 [用戶名稱]、[密碼] 和 [確認密碼] 字段。

  10. 現在 [身分識別 ] 值應該會顯示如下:

    [進階設定] 對話框的螢幕快照,其中 [進程模型] 區段中醒目提示 [識別] 值。

  11. 按一下 [確定] 以儲存變更。

  12. 針對 AppPool2 重複上一個步驟,並將使用者名稱為 “AppPoolIdentity2” 和密碼 “password2”。

  13. 您會看到 IIS 管理員中顯示的下列內容(主要是應用程式集區的身分識別已變更):

    顯示應用程式集區已變更身分識別的應用程式集區螢幕快照。

  14. 使用 Windows 記事本並開啟 %SystemRoot%\System32\Inetsrv\applicationHost.config 檔案來確認變更。 瀏覽至 applicationPools 區段,您會看到我們已如預期般使用 Rsa_WAS 金鑰加密應用程式集區密碼:

    password="[enc:Rsa_WAS:jAAAAAECAAADZgAAAKQAAAUkBfhWFbUHIt/qtlo+P7CiZC10r9H0DGBvAl
                 U2mhiOxMoHXX6Dz0S8TQjKx2YTKvuE8y+SBUWrEs3JYzXKOkY45Q9z6E/3BFvru5oR9uzbjInASKF/83N
                 N1tIEsoorQWmUOjnL4XM9RNzpqkY6TgyC3CyPUGN9fR7li5+AUupHHfgVPMzcLHfCsoq+ri+X6IbEnJdu
                  cUEAYBn1P9F/Zxk=:enc]" />
                  password="[enc:Rsa_WAS:jAAAAAECAAADZgAAAKQAAEbQEa/sAmyLbryAR0hD3voip2+0RfzM44sXPekp
                  I2H7HYLzta55NfLcG8vSPHhasahKVgO4wcIcT03CLSn+5koWvAaIRdeClhXWK/X8ZQPFooOpyhOqT0TEP5v
                  jB+DXAKgq0RC6ufHFtrHMy0U69ew7/49YXEcrkF+o8OJZ1K+EkgA3J2ikHKxW0pFBU0tFvLCjt2/UXypfNI
                  0hYPe2syk=:enc]" />
    

封鎖加密提供者

根據預設,IIS_IUSRS會在建立金鑰時獲得金鑰的讀取許可權。 不過,您可以使用 ASPNET_REGIIS 工具來移除該存取權。 若要這樣做,請在以系統管理員身分執行的命令提示字元中執行下列命令:

cd /d %systemroot%
cd Microsoft.NET\Framework\v2.0.50727
aspnet_regiis.exe -pr iisWasKey IIS_IUSRS

這移除了 IIS_IUSRS(應用程式集區身分識別群組)對 iisWasKey 的讀取權限,而 iisWasKey 的權限僅限於系統管理員和 LOCALSYSTEM 存取。

工作程序隔離

本主題說明如何建立屬於不同應用程式集區一部分且具有不同匿名驗證身分識別的兩個新月臺,以設定背景工作進程隔離。 然後,我們會為每個應用程式集區建立新的 RSA 提供者,以加密匿名密碼。

建立新網站

在本節中,我們會建立兩個新的網站,並將每個網站新增至我們稍早建立的應用程式集區。 若要開始,請使用下列步驟開啟以系統管理許可權執行的命令殼層:

  1. 按兩下 [ 開始] 選單。

  2. 以滑鼠右鍵點擊 [命令提示字元]。

  3. 選取 [ 以系統管理員身分執行]。

  4. 在命令視窗中,使用下列命令流覽至 wwwroot 目錄:

    cd /d %SystemDrive%\inetpub\wwwroot
    
  5. 使用下列指令建立名為 「one」 的新目錄與目錄 「two」 :

    mkdir one
    
    mkdir two
    
  6. 在 “one” 和 “two” 目錄中建立包含下列 HTML 程式代碼的基本 Default.htm 檔案:

    <html><body>Hello from site X</body></html>
    

    備註

    根據檔案的目錄位置,將 『X' 取代為 『one』 或 'two'。

現在,使用 IIS 管理員建立兩個月臺:

  1. 按兩下 [開始],輸入 INetMgr.exe ,然後按 Enter 鍵(如果出現提示,請選取 [ 繼續 ] 以提升您的許可權)。

  2. 按兩下 + [ 連線 ] 區段中您電腦名稱旁邊的按鈕。

  3. 以滑鼠右鍵按兩下 [連線] 下方樹檢視中的 [網站],然後選取 [新增網站]。

  4. 使用下列資訊來建立您的網站:

    網站名稱:一個
    應用程式集區:AppPool1
    實體路徑: {inetpub 目錄的位置}\wwwroot\one
    埠:81

    完成時,這看起來應該如下所示:

    [新增網站] 對話框的螢幕快照,其中 [網站名稱] 字段正在填入 One 專案。

  5. 按一下 [確定],儲存變更。

  6. 重複上述兩個步驟,但這次針對第二個地點使用下列資訊:

    網站名稱:兩個
    應用程式集區:AppPool2
    實體路徑: {inetpub 目錄的位置}\wwwroot\two
    埠:82

您現在已建立兩個名為 OneTwo 的新網站,並將其新增至 AppPool1AppPool2 應用程式集區。

用來測試網站的網址如下:

  • http://localhost:81 針對網站 One
  • http://localhost:82 適用於場所

為每個應用程式集區建立新的提供者

在本節中,我們會為每個應用程式集區建立新的 RSA 提供者:

  1. 按一下開始選單。

  2. 以滑鼠右鍵按兩下 [命令提示字元]。

  3. 選取 [ 以系統管理員身分執行]。

  4. 在命令視窗中,流覽至您儲存 createProvider.exe 的位置,然後執行下列命令:

    createProvider.exe App1Key RsaKeyForAppPool1 Rsa_app1
    createProvider.exe App2Key RsaKeyForAppPool2 Rsa_app2
    

設定網站 One 的匿名帳戶

在提升許可權的命令提示字元視窗中,執行下列命令:

setProvider.exe Rsa_app1
  1. 返回 IIS 管理器,然後雙擊網站 One

  2. 雙擊 [驗證] 專案於 [功能名稱] 標題下。

  3. 選取 [匿名驗證],然後按下右側 [工作] 標題下的 [編輯] ,以顯示 [編輯匿名驗證認證] 對話方塊。

  4. 按兩下 [ 特定使用者] 選項,然後按下 [ 設定 ] 按鈕。

  5. 輸入 Username AnonymousAccount1 和密碼 password3 ,然後選取 [ 確定]。

  6. 這會顯示下列對話框:

    [編輯匿名驗證認證] 對話框的螢幕快照。

  7. [確定 ] 儲存變更。

設定站點二的匿名帳戶

在權限提升的命令提示字元窗口中,執行下列命令:

setProvider.exe Rsa_app2
  1. 回到IIS 管理器,然後雙擊網站Two
  2. 按兩下 驗證 項目,位於 功能名稱 標題下。
  3. 選取 [匿名驗證],然後按下右側 [工作] 標題下的 [編輯] ,以顯示 [編輯匿名認證] 對話方塊。
  4. 按兩下 [ 特定使用者] 選項,然後按下 [ 設定]。
  5. 輸入 Username AnonymousAccount2 和密碼 password4 ,然後選取 [ 確定]。
  6. 按一下 [確定] 以儲存變更。

將加密提供者重設為預設值

  • 返回高權限命令提示字元視窗,然後執行下列命令:
setProvider.exe RsaProtectedConfigurationProvider

備註

這項變更可確保所有加密的未來屬性都使用預設加密提供者。

確認變更

確認我們想要執行的動作。 使用 Windows 記事本開啟檔案 %SystemRoot%\System32\Inetsrv\applicationHost.config

  • 請注意, AppPool1AppPool2 的密碼仍會受到 Rsa_Was 密鑰的保護。

  • 請注意, AnonymousAccount1 的密碼也會受到 Rsa_app1 密鑰的保護:

    password="[enc:Rsa_app1:jAAAAAECAAADZgAAAKQAAKoz4LV7HyPQuyNzXh8gspB0rPG7j3Ijvn3d+jY3/f
        gma8ZxA7AHLUxjis9b0+Qu8XkLvsGn/A+F+m1O68gY1LkWzAcSW9ks81FuiBVhpZx73FzEo6aOz2QqBduJ7Xhu
        x923KMBqmwkIVJ0mVAdzwFIm6LWymwRXxNxDE4eosKsw6QP6Rd6duC8gckaLxrTndclErQYgGdMt3W6ofxzRMlc=:enc]" />
    
  • 最後,請注意 ,AnonymousAccount2 密碼也會受到 Rsa_app2 密鑰的保護:

    password="[enc:Rsa_app2:jAAAAAECAAADZgAAAKQAAKmHMhCTICEUhGncSGCxQc6ll/QGXo0asEIzOf3rIjl
     sBDGRYhlDQWlf2QbFcIsBGYt8dHo9hzAQN/f03BPSlaFynevpSx4xJOg2/B8ATgPmCg4vgxpY5huZbGxongs55c
       Rr20WFXsxzlUuw1xoUZI8c1+7gQPOtF0Rwh1g8NBmb5ML/R3jAIFcMtVhaj0OOIfAP7JCjdInwztBqK0XO7FM=:enc]" />
    

鎖定加密提供者

如先前所述,保護密鑰的檔案許可權。 從提升權限的指令提示字元執行下列命令:

cd /d %systemroot%
cd Microsoft.NET\Framework\v2.0.50727
aspnet_regiis.exe -pr App1Key IIS_IUSRS
aspnet_regiis.exe -pa App1Key   AppPoolIdentity1
aspnet_regiis.exe -pr App2Key IIS_IUSRS
aspnet_regiis.exe -pa App2Key   AppPoolIdentity2

這些命令已移除IIS_IUSRS讀取金鑰的能力,並只新增需要密鑰訪問許可權的應用程式集區身分識別。

測試您的網站

現在測試您的網站:

  • http://localhost:81
  • http://localhost:82

一切都應該像以前一樣繼續運作。

總結

總而言之,我們執行了下列工作來保護應用程式集區設定:

  • 已建立兩個應用程式集區
  • 建立兩個本機用戶帳戶,並將其設定為應用程式集區身分識別
  • 我們建立了系統管理加密金鑰,並用它來保護所有應用程式集區身分識別密碼
  • 我們使用ASPNET_REGIIS來移除IIS_IUSRS (應用程式集區身分識別群組) 來存取密鑰

這些工作有效地確保只有系統管理員和 SYSTEM 帳戶可以讀取應用程式集區的密碼。 因此,如果應用程式集區內的應用程式嘗試擷取其 (或任何) 應用程式集區的密碼,嘗試將會失敗。

若要隔離工作者進程設定,我們會:

  • 已建立新的匿名身分識別帳戶
  • 我們已為應用程式集區建立新的提供者
  • 我們已使用應用程式集區金鑰加密匿名驗證密碼
  • 我們已移除對IIS_IUSRS的匿名驗證提供者的存取,並只授與應用程式集區身份的存取權。

這可有效地確保只有應用程式集區身分識別能夠解密它所屬的匿名密碼,其他任何人都不行。