安全機密管理:Asp.Net Core中的本地敏感資料保護技巧

董瑞鹏發表於2024-04-25

前言

在我們開發過程中基本上不可或缺的用到一些敏感機密資料,比如SQL伺服器的連線串或者是OAuth2Secret等,這些敏感資料在程式碼中是不太安全的,我們不應該在原始碼中儲存密碼和其他的敏感資料,一種推薦的方式是透過Asp.Net Core機密管理器

機密管理器

ASP.NET Core 中,機密管理器通常指的是一種工具或機制,用於安全地儲存和管理應用程式中的敏感資料,如資料庫連線字串、API 金鑰、密碼等。這樣的工具可以幫助開發人員有效地管理敏感資訊,避免將其硬編碼在程式碼中或與原始碼一同提交到版本控制系統中,從而提高資料安全性和保密性。

透過上面我們可以得知,應用機密儲存和專案數在不同的位置,也就是說不被 git 等原始碼管理器所管理,所以不會隨原始碼遷入到遠端伺服器。

為什麼要使用機密管理器:

  • 安全性:透過使用機密管理器,可以將敏感資料儲存在安全的位置,避免在程式碼中明文儲存密碼等敏感資訊,從而減少資料洩露的風險。

  • 便捷性:機密管理器提供了方便的方式來儲存和訪問敏感資料,使開發人員能夠輕鬆地在開發過程中使用這些資料,而無需擔心洩露或不當處理。

  • 靈活性:透過機密管理器,可以輕鬆地在不同環境中管理不同的敏感資料,如開發、測試和生產環境,同時確保每個環境中的資料安全性。

  • 遵循最佳實踐:使用機密管理器有助於遵循最佳實踐,如將敏感資料與應用程式程式碼分離、避免硬編碼密碼等敏感資訊,提高應用程式的安全性和可維護性。

如何啟用機密儲存

有兩種方案第一種是使用CLI第二種是使用Visual Studio

我們建立一個新的WebApi 專案dotNetParadise.UserSecret

使用CLI

機密管理器工具包含一個 init 命令 用來啟用機密儲存,在專案所在的目錄,在我的示例中就是Api專案dotNetParadise.UserSecret的所在目錄執行一下命令:

dotnet user-secrets init

image

透過輸出我們可以看到在我們專案的CSPROJ檔案生成了一個UserSecretsId 元素新增到專案檔案的 PropertyGroup 中,內部文字是任意的,但對於專案來說是唯一的。

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UserSecretsId>c3cda712-dc63-439b-b6af-9c4d6060fde2</UserSecretsId>
  </PropertyGroup>

設定機密

使用 dotnet user-secrets set 命令來儲存機密資料。

在專案資料夾目錄中執行此命令

dotnet user-secrets set "Movies:ServiceApiKey" "12345"

在這個示例中,使用 dotnet user-secrets set 命令設定了一個名為 "Movies:ServiceApiKey" 的應用機密,其值為 "12345"。冒號表示 "Movies" 是具有 "ServiceApiKey" 屬性的物件文字。

我們設定好的機密資料存到了哪裡?

Windows系統中

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

比如我剛才新增的就在機密儲存位置:

%APPDATA%\Microsoft\UserSecrets\c3cda712-dc63-439b-b6af-9c4d6060fde2\secrets.json

image

看一下里面的內容

{
  "Movies:ServiceApiKey": "12345"
}

也可以透過單擊該專案(專案名稱),然後從上下文選單中選擇“管理使用者機密”設定,在VS編輯器檢視secrets.json機密資料。

--project 屬性

除了在專案檔案目錄中執行dotnet user-secrets set命令設定機密之外,還可以在透過 --project 選項用於指定專案檔案所在的檔案系統路徑,以便在其他目錄中使用User Secrets機密管理器工具,這種用法允許從任意目錄設定應用機密,而不僅限於專案檔案所在的當前目錄

dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"

機密管理器工具不會加密儲存的機密,不得被視為受信任的儲存,它僅用於開發,金鑰和值儲存在使用者配置檔案目錄中的 JSON 配置檔案中。

使用Visual Studio

當在 Visual Studio 中進行敏感資料管理時,可以按照以下步驟操作:

  • 在解決方案資源管理器中右鍵 單擊該專案(專案名稱),然後從上下文選單中選擇“管理使用者機密”

  • Visual Studio 將自動為該專案新增一個 UserSecretsId 元素,其中填充有一個唯一的 GUID

image

設定完之後在 VS 的編輯介面就會開啟一個secrets.json檔案

{}

這裡面是一個空的 json 串,可以手動設定機密鍵值物件,也可以透過dotnet user-secrets set來設定機密資料

批次設定機密

可以透過一個json檔案來批次設定機密

type .\input.json | dotnet user-secrets set

讀取機密

Asp.Net Core 中我們在專案中讀取配置如appSetting.json或者環境變數的引數都是透過IConfiguration物件來操作,機密的讀取和Asp.Net Core的配置都是一樣的我們來實戰一下

var apiKey = builder.Configuration["Movies:ServiceApiKey"];
Console.WriteLine(apiKey);

image

可以看到機密資訊已經正常讀到。

配置的優先順序

那麼如果 user-secretsappSetting.json或者還有其他的配置源設定相同的資料,那個優先順序高呢?

根據Asp.Net Core 配置介紹

WebApplication.CreateBuilder 使用預配置的預設值初始化 WebApplicationBuilder 類的新例項。 經過初始化的 WebApplicationBuilder (builder) 按照以下順序為應用提供預設配置(從最高優先順序到最低優先順序):

  • 使用命令列配置提供程式透過命令列引數提供。
  • 使用非字首環境變數配置提供程式透過非字首環境變數提供。
  • 應用在 Development 環境中執行時的使用者機密。
  • 使用 JSON 配置提供程式透過 appsettings.{Environment}.json 提供。 例如,appsettings.Production.jsonappsettings.Development.json
  • 使用 JSON 配置提供程式透過 appsettings.json 提供。

可以看出如果使用者機密比預設的 appsettings.json 優先順序要高。

對應機密的繫結成POCO物件和 Asp.Net Core 使用配置一樣可以用IConfiguration提供的各種擴充套件如Get,Bind等來實現,此處不過多介紹

列出機密

從所在專案目錄中執行

dotnet user-secrets list

輸出:

Movies:ServiceApiKey = 12345

刪除單個機密

dotnet user-secrets remove Movies:ServiceApiKey

使用 dotnet user-secrets remove 命令來刪除 ASP.NET Core 專案中的單個機密。在這個示例中,執行命令 dotnet user-secrets remove Movies:ServiceApiKey 將刪除名為 "Movies:ServiceApiKey" 的機密資訊。

透過這種方式,你可以方便地管理和更新專案中的機密資料,確保不再需要的敏感資訊不再儲存在使用者機密儲存中。

刪除所有機密

dotnet user-secrets clear

dotnet user-secrets clear 用於清除 ASP.NET Core 專案中儲存的所有使用者機密。執行這個命令將刪除使用者機密儲存中的所有機密資訊,使儲存中不再包含任何敏感資料。

使用 dotnet user-secrets clear 命令是一種快速清除整個使用者機密儲存中資料的方式,適用於需要重置或清除所有敏感資訊的情況。請謹慎使用此命令,確保在執行之前備份重要的機密資料。

最後

面向非Web的環境,可以參考下方官網的實現,本文注重講解了透過user-secrets來管理本地的機密,線上環境的機密配置可以ASP.NET Core 中的 Azure Key Vault 配置提供程式,或者大家如果在k8s的環境中可以透過Secret或者ConfigMap,亦或是配置中心等方式來讓自己的機密資訊避免在原始碼中出現。

  • 在開發過程中保護機密
    😄歡迎關注筆者公眾號一起學習交流,獲取更多有用的知識~
    image

相關文章