ASP.NET Core 中的目的字串
取用 IDataProtectionProvider
的元件必須將唯一目的參數傳遞至 CreateProtector
方法。 目的參數是資料保護系統的安全性所既有的,因為它提供密碼編譯取用者之間的隔離,即使根密碼編譯金鑰相同也一樣。
當取用者指定目的時,目的字串會與根密碼編譯金鑰搭配使用,以衍生該取用者唯一的密碼編譯子機碼。 這會隔離取用者與應用程式中所有其他密碼編譯取用者:沒有其他元件可以讀取其承載,而且無法讀取任何其他元件的承載。 此隔離也使針對該元件所有類別的攻擊變得不可行。
在上圖中,IDataProtector
執行個體 A 和 B 無法讀取彼此的承載,只能讀取自己的承載。
目的字串不一定是秘密。 它應該只是唯一的,因為沒有任何其他表現良好的元件會提供相同目的字串。
提示
使用取用資料保護 API 之元件的命名空間和類型名稱,是良好的經驗法則,因為實際上這項資訊永遠不會衝突。
負責挖掘持有人權杖的 Contoso 撰寫元件,可能會使用 Contoso.Security.BearerToken 作為其目的字串。 或者,它可能會使用 Contoso.Security.BearerToken.v1 作為其目的字串會更好。 附加版本號碼可讓未來的版本使用 Contoso.Security.BearerToken.v2 做為其目的,而且就承載而言,不同的版本會完全彼此隔離。
由於 CreateProtector
的目的參數是字串陣列,因此上述參數可以改指定為 [ "Contoso.Security.BearerToken", "v1" ]
。 這可建立目的階層,並開啟使用資料保護系統的多租用戶案例的可能性。
警告
元件不應允許不受信任的使用者輸入成為目的鏈結的唯一輸入來源。
例如,請考量負責儲存安全訊息的 Contoso.Messaging.SecureMessage 元件。 如果安全傳訊元件要呼叫 CreateProtector([ username ])
,惡意使用者可能會建立一個使用者名稱為「Contoso.Security.BearerToken」的帳戶,以嘗試讓元件呼叫 CreateProtector([ "Contoso.Security.BearerToken" ])
,因此無意中導致安全傳訊系統產生可能被視為驗證權杖的承載。
傳訊元件較佳的目的鏈結是 CreateProtector([ "Contoso.Messaging.SecureMessage", $"User: {username}" ])
,可提供適當的隔離。
IDataProtectionProvider
、IDataProtector
和目的所提供的隔離行為如下:
對於指定的
IDataProtectionProvider
物件,CreateProtector
方法將建立一個唯一繫結到建立它的IDataProtectionProvider
物件,和傳遞到該方法目的參數的IDataProtector
物件。目的參數不得為 Null。 (如果將目的指定為陣列,這表示陣列不得為零長度,而且陣列的所有元素都必須非 Null。)空字串目的技術上是允許的,但不建議使用。
如果而且僅有當兩個目的引數包含相同順序的相同字串 (使用序數比較子) 時,則兩個目的引數是相等的。 單一目的引數相當於對應的單一元素目的陣列。
兩個
IDataProtector
物件只有在使用對等目的參數的對等IDataProtectionProvider
物件建立時,才會相等。針對指定的
IDataProtector
物件,只有在對等IDataProtector
物件的protectedData := Protect(unprotectedData)
時,對Unprotect(protectedData)
的呼叫才會傳回原始unprotectedData
。
注意
我們不考慮某些元件刻意選擇已知與另一元件衝突的目的字串情況。 這類元件基本上會被視為惡意,而且在惡意程式碼已在背景工作處理序內執行時,此系統不打算提供安全性保證。