Zweckzeichenfolgen in ASP.NET Core
Komponenten, die IDataProtectionProvider
nutzen, müssen an die CreateProtector
-Methode einen eindeutigen Zweck-Parameter übergeben. Der Zweck-Parameter ist ein wesentlicher Bestandteil der Sicherheit des Datenschutzsystems, da er eine Isolation zwischen kryptografischen Consumern ermöglicht, selbst wenn die kryptografischen Stammschlüssel identisch sind.
Wenn ein Consumer einen Zweck angibt, wird die Zweckzeichenfolge zusammen mit den kryptografischen Stammschlüsseln verwendet, um kryptografische Unterschlüssel abzuleiten, die nur für diesen Consumer eindeutig sind. Dadurch wird der Consumer von allen anderen kryptographischen Consumern in der Anwendung isoliert. Keine andere Komponente kann seine Nutzdaten lesen, und er kann die Nutzdaten keiner anderen Komponente lesen. Diese Isolation macht auch ganze Kategorien von Angriffen auf die Komponente undurchführbar.
Im obigen Diagramm können die IDataProtector
-Instanzen A und B nicht die Nutzdaten der jeweils anderen lesen, sondern nur ihre eigenen.
Die Zweckzeichenfolge muss nicht geheim sein. Sie muss in dem Sinne eindeutig sein, dass keine andere ordnungsgemäß funktionierende Komponente jemals dieselbe Zweckzeichenfolge bereitstellt.
Tipp
Die Verwendung von Namespace und Typname der Komponente, die die Datenschutz-APIs nutzt, ist eine gute Faustregel, da diese Informationen in der Praxis nie in Konflikt stehen werden.
Eine von Contoso entwickelte Komponente, die für das Ausstellen von Token zuständig ist, kann Contoso.Security.BearerToken als Zweckzeichenfolge verwenden. Oder sie kann – noch besser – Contoso.Security.BearerToken.v1 als Zweckzeichenfolge nutzen. Durch das Anfügen der Versionsnummer kann eine künftige Version Contoso.Security.BearerToken.v2 als Zweck verwenden, wodurch die verschiedenen Versionen in Bezug auf Nutzdaten vollständig voneinander isoliert bleiben.
Da der Zweckparameter für CreateProtector
ein Zeichenfolgenarray ist, kann die obige Angabe stattdessen als [ "Contoso.Security.BearerToken", "v1" ]
erfolgen. Dies ermöglicht eine Zweckhierarchie und eröffnet die Möglichkeit mehrinstanzenfähiger Szenarien mit dem Datenschutzsystem.
Warnung
Komponenten dürfen nicht zulassen, dass nicht vertrauenswürdige Benutzereingaben die einzige Eingabequelle für die Zweckkette sind.
Betrachten Sie beispielsweise die Komponente Contoso.Messaging.SecureMessage, die für das Speichern sicherer Nachrichten zuständig ist. Wenn die sichere Messagingkomponente CreateProtector([ username ])
aufruft, könnte ein böswilliger Benutzer ein Konto mit dem Benutzernamen Contoso.Security.BearerToken erstellen, um zu versuchen, die Komponente zum Aufrufen von CreateProtector([ "Contoso.Security.BearerToken" ])
zu veranlassen. Dadurch würde das sichere Messagingsystem versehentlich Nutzdaten ausstellen, die als Authentifizierungstoken wahrgenommen werden könnten.
Eine bessere Zweckkette für die Messagingkomponente wäre CreateProtector([ "Contoso.Messaging.SecureMessage", $"User: {username}" ])
, wodurch eine ordnungsgemäße Isolation ermöglicht wird.
Die Isolation durch und das Verhalten von IDataProtectionProvider
, IDataProtector
und die Zwecke sind wie folgt:
Für ein bestimmtes
IDataProtectionProvider
-Objekt erstellt dieCreateProtector
-Methode einIDataProtector
-Objekt, das eindeutig sowohl an dasIDataProtectionProvider
-Objekt, das es erstellt hat, als auch an den Zweckparameter, der an die Methode übergeben wurde, gebunden ist.Der Zweckparameter darf nicht NULL sein. (Wenn Zwecke als Array angegeben werden, bedeutet dies, dass das Array nicht die Länge 0 haben darf und dass alle Elemente des Arrays ungleich NULL sein müssen.) Die Angabe einer leeren Zweckzeichenfolge ist technisch zulässig, aber nicht empfehlenswert.
Zwei Zweckargumente sind nur dann gleichwertig, wenn sie die gleichen Zeichenfolgen (unter Verwendung eines Ordinalvergleichs) in der gleichen Reihenfolge enthalten. Ein einzelnes Zweckargument entspricht dem entsprechenden Array für Zwecke mit einem einzelnen Element.
Zwei
IDataProtector
-Objekte sind nur dann gleichwertig, wenn sie aus gleichwertigenIDataProtectionProvider
-Objekten mit gleichwertigen Zweckparametern erstellt wurden.Für ein gegebenes
IDataProtector
-Objekt gibt ein Aufruf vonUnprotect(protectedData)
nur dann das ursprünglicheunprotectedData
zurück, wennprotectedData := Protect(unprotectedData)
für ein gleichwertigesIDataProtector
-Objekt gilt.
Hinweis
Wir betrachten nicht den Fall, bei dem eine Komponente absichtlich eine Zweckzeichenfolge wählt, von der bekannt ist, dass sie mit einer anderen Komponente in Konflikt steht. Eine solche Komponente wäre im Grunde genommen als schädlich anzusehen, und dieses System ist nicht dazu gedacht, Sicherheitsgarantien für den Fall zu bieten, dass schädlicher Code bereits innerhalb des Workerprozesses ausgeführt wird.