簡體   English   中英

使用 Windows .NET 或 ASP.NET 應用程序時存儲數據庫密碼的位置

[英]Where to store db passwords when using Windows .NET or ASP.NET applications

我有一個困擾我多年的場景。 如果您必須使用用戶名和密碼連接到數據庫或其他服務(如 Web 服務),如果您通過 .NET 程序集進行連接,那么存儲此信息的最安全位置是什么? 我知道您必須對密碼進行加密,但隨后您遇到了一種雞蛋問題——很好——您可以對其進行加密,但是您將密鑰放在哪里?

在 .NET 中,您不能對密碼進行硬編碼,因為您可以反編譯 .NET 代碼。

我曾考慮在隔離存儲中使用基於程序集的權限,但 MS 建議不要在那里存儲未加密的機密項目,因為特權用戶可以獲得訪問權限,因此,我們再次將問題從 A 點移至 B 點。例如,域管理員無需了解數據庫中的信息就可以訪問,因為能夠成為域中任何工作站的管理員。

您可以加密應用程序。 Config 和 Web.Config,但我相信特權用戶可以訪問密鑰。

我認為您在使用 DPAPI 時遇到了同樣的問題。

我曾考慮將密碼存儲在遠程數據庫中,加密並通過操作系統身份驗證獲取,但我們部門禁止將密碼存儲在數據庫服務器上。 我很確定我被卡住了,需要確認。

您不想將密碼存儲在程序集中,重新發明輪子只會帶來更多的麻煩(並引入更多的漏洞)。 如果您在數據庫和 Web 服務器上都使用 MS 平台,那么處理此問題的最簡單方法是使用受信任的連接,並將 SQL 服務器上的權限授予您的應用程序使用的身份。

其次,我會讓 DPAPI 完成它的工作來加密您的連接設置

您可以使用.NET Framework的以下方法來保護您的數據; 它們在內部使用DPAPI來保護您的數據,您可以直接在 C# 或 VB.NET 中使用它們,而無需擺弄系統 DLL 調用:

namespace System.Security.Cryptography
{
    // Summary:
    //     Provides methods for protecting and unprotecting data. This class cannot
    //     be inherited.
    public sealed class ProtectedData
    {
        public static byte[] Protect(byte[] userData, 
            byte[] optionalEntropy, DataProtectionScope scope);
        public static byte[] Unprotect(byte[] encryptedData, 
            byte[] optionalEntropy, DataProtectionScope scope);
    }
}

要使用它,請將參考System.Security添加到您的項目中。 我強烈建議使用字節數組optionalEntropy向受保護的數據添加SALT (向字節數組添加一些隨機值,這些值對於您打算保護的數據是唯一的)。

對於scope您可以使用DataProtectionScope.CurrentUser ,它將加密數據以使用當前用戶的憑據進行保護。

在某些情況下, DataProtectionScope.LocalMachine也很有用。 在這種情況下,受保護的數據與機器上下文相關聯。 使用此設置,計算機上運行的任何進程都可以取消保護數據。 它通常用於在不允許不受信任的用戶訪問的服務器上運行的特定於服務器的應用程序。

使用Protect方法加密數據,使用Unprotect解密。 您可以根據應用程序的要求(文件、數據庫、注冊表等)存儲返回的字節數組。

有關這些方法的更多信息,請訪問 MSDN:

對於代碼示例,如果您對加密應用程序的 .config 文件的某些部分感興趣,請查看以下內容:

我建議您使用SALT (通過使用optionalEntropy參數) - 它可以防止彩虹表攻擊。


我想提一下 DPAPI 解決方案的一個缺點:密鑰是根據您的 Windows 憑據生成的,這意味着任何有權訪問您的 Windows 憑據的人都可能有權訪問受保護的數據。 在您的帳戶下運行的程序也可以訪問受保護的數據。

****針對 Windows 10 1903+ 進行更新 ****

Microsoft 已從 WinMetadata 中刪除了先前方法使用的 dll,即使在執行舊操作時,它們現在也不可用。 相反, 他們現在建議使用 Target Framework Moniker 或名為Microsoft.Windows.SDK.Contracts 的 Nuget 包來公開現代 Windows API。 [官方詳細信息可以在這里找到]。 請注意,要正確安裝 nuget,必須將數據包管理設置為PackageReference而不是Packages.config否則,即使它看起來像是已安裝,它也不會工作。

如果尚未設置為此管理器,通常可以通過右鍵單擊 packages.config 文件並選擇Migrate將 packages.config 文件轉換為新格式(集成在項目文件中)。 如果 Packages.config 文件尚不存在,則可以通過進入 Nuget 選項將默認設置設置為使用 PackageReference。 請注意,默認設置在 .Net FW、.Net Std 和 .Net Core 之間有所不同。 當我個人不得不這樣做時,奇怪的是,它不想遷移文件。 我必須完全卸載我的軟件包,刪除文件,設置默認值並重新安裝軟件包。 如果我沒記錯的話,這和 TFVC 有關系。

API 應該會再次可用。

**** 原帖 ****

如果您使用的是僅限 Windows 8+ 的解決方案,您還可以使用 Windows 密碼保管庫。 最初,這是為 Metro 應用程序構建的,但也支持 Winform 和 WPF 應用程序。

基本上,你需要的是

  1. 在第一個屬性組內的項目文件中添加以下行
    <TargetPlatformVersion>8.0</TargetPlatformVersion>

  2. 參考Windows.Security

    • 打開引用管理器窗口
    • 選擇Windows選項卡
    • 選擇Core子選項卡
    • 檢查Windows.Security
  3. 在代碼中,使用(這是 vb 但 C# 是等效的)

     Dim vault = New Windows.Security.Credentials.PasswordVault() vault.Add(New Windows.Security.Credentials.PasswordCredential(resource, userName, password)) Dim cred = vault.Retrieve(resource, logon) cred.RetrievePassword() Dim pwd = cred.Password

參考:

  1. https://docs.microsoft.com/fr-ca/archive/blogs/cdndevs/using-windows-8-winrt-apis-in-net-desktop-applications
  2. https://docs.microsoft.com/en-us/uwp/api/Windows.Security.Credentials.PasswordVault?view=winrt-19041

這是個好問題,我自己一直在尋找答案。 我遇到的問題是確保數據庫密碼安全,以防服務器被黑客入侵並且可以檢索單個文件。 我發現的一個非常有趣的選項是 web.config 的部分可以由 .NET 框架自動加密和解密,該框架將使用 Windows 安全存儲為您保存和檢索加密密鑰。 在我的情況下不可用,因為我的托管服務提供商不支持它,但您可以查看此選項。 我認為它可能有效的原因是您可以獨立管理用戶可能訪問 Windows 安全存儲的安全性,並顯着限制任何潛在的違規行為。 闖入服務器的黑客可能會獲得您的配置文件和所有程序集的副本,但訪問解密密鑰將是他的另一個障礙。

這里有幾個選項。

  1. 將它們存儲在加密的配置文件中
  2. 將它們存儲在使用生成的種子加密的外部文件中。 混淆存儲此基本種子的代碼或將其存儲在 c++ dll 中(難以反編譯)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM