Sleutelbeheer in ASP.NET Core
Het systeem voor gegevensbeveiliging beheert automatisch de levensduur van hoofdsleutels die worden gebruikt om nettoladingen te beveiligen en op te heffen. Elke sleutel kan bestaan in een van de vier fasen:
Gemaakt: de sleutel bestaat in de sleutelring, maar is nog niet geactiveerd. De sleutel mag niet worden gebruikt voor nieuwe protect-bewerkingen totdat voldoende tijd is verstreken dat de sleutel de kans heeft gehad om door te geven aan alle computers die deze sleutelring gebruiken.
Actief: de sleutel bestaat in de sleutelring en dient te worden gebruikt voor alle nieuwe Protect-bewerkingen.
Verlopen: de sleutel heeft zijn natuurlijke levensduur bereikt en zou niet langer gebruikt moeten worden voor nieuwe beschermingsbewerkingen.
Ingetrokken: de sleutel is gecompromitteerd en mag niet worden gebruikt voor nieuwe beveiligingsbewerkingen.
Gemaakte, actieve en verlopen sleutels kunnen allemaal worden gebruikt om binnenkomende gegevenspakketten te ontsleutelen. Ingetrokken sleutels kunnen standaard niet worden gebruikt om de beveiliging van nettoladingen op te heffen, maar de ontwikkelaar van de toepassing kan dit gedrag zo nodig overschrijven.
Waarschuwing
De ontwikkelaar kan geneigd zijn om een sleutel uit de sleutelring te verwijderen (bijvoorbeeld door het bijbehorende bestand uit het bestandssysteem te verwijderen). Op dat moment zijn alle gegevens die door de sleutel worden beschermd permanent onontcijferbaar en is er geen noodoplossing zoals er wel is met ingetrokken sleutels. Het verwijderen van een sleutel is echt destructief gedrag.
Standaardsleutelselectie
Wanneer het systeem voor gegevensbescherming de sleutelring uit de achterliggende opslagplaats leest, probeert het een "standaard" sleutel uit de sleutelring te vinden. De standaardsleutel wordt gebruikt voor nieuwe beveiligingsbewerkingen.
De algemene heuristiek is dat het systeem voor gegevensbeveiliging de sleutel kiest met de meest recente activeringsdatum als standaardsleutel. (Er is een kleine fudgefactor die scheeftrekken van de server-naar-serverklok toestaat.) Als de sleutel is verlopen of ingetrokken en als de toepassing het automatisch genereren van sleutels niet heeft uitgeschakeld, wordt er een nieuwe sleutel gegenereerd met onmiddellijke activering volgens het verlopen van de sleutel en het rolling-beleid hieronder.
De reden waarom het systeem voor gegevensbeveiliging onmiddellijk een nieuwe sleutel genereert in plaats van terug te vallen op een andere sleutel, is dat het genereren van nieuwe sleutels moet worden behandeld als een impliciete vervaldatum van alle sleutels die vóór de nieuwe sleutel zijn geactiveerd. Het algemene idee is dat nieuwe sleutels mogelijk zijn geconfigureerd met verschillende algoritmen of versleuteling in rusttoestand-mechanismen dan oude sleutels, en het systeem zou de voorkeur moeten geven aan de huidige configuratie boven terugvallen.
Er is een uitzondering. Als de toepassingsontwikkelaar automatische sleutelgeneratie uitgeschakeld, moet het systeem voor gegevensbeveiliging iets als de standaardsleutel kiezen. In dit terugvalscenario kiest het systeem de niet-ingetrokken sleutel met de meest recente activeringsdatum, waarbij de voorkeur wordt gegeven aan sleutels die tijd hebben gehad om door te geven aan andere computers in het cluster. Het terugvalsysteem kan uiteindelijk een verlopen standaardsleutel kiezen. Het terugvalsysteem kiest nooit een ingetrokken sleutel als de standaardsleutel en als de sleutelring leeg is of elke sleutel is ingetrokken, zal het systeem een fout veroorzaken bij de initialisatie.
Sleutelverloop en -vernieuwing
Wanneer een sleutel wordt gemaakt, krijgt deze automatisch een activeringsdatum van { now + 2 days } en een vervaldatum van { now + 90 days }. De 2-daagse vertraging voor activering geeft de sleutel de tijd om zich te verspreiden door het systeem. Dit betekent dat andere toepassingen die wijzen naar de achterliggende opslag de sleutel kunnen observeren tijdens hun volgende automatische vernieuwingsperiode, waardoor de kans maximaal is dat wanneer de sleutelhanger actief wordt, deze is doorgegeven aan alle toepassingen die deze mogelijk moeten gebruiken.
Als de standaardsleutel binnen 2 dagen verloopt en de sleutelring nog geen sleutel heeft die actief zal zijn bij het verlopen van de standaardsleutel, zal het gegevensbeschermingssysteem automatisch een nieuwe sleutel aan de sleutelring toevoegen. Deze nieuwe sleutel heeft een ingangsdatum die gelijk is aan de vervaldatum van de standaardsleutel en een vervaldatum van over 90 dagen vanaf nu. Hierdoor kan het systeem regelmatig sleutels automatisch uitrollen zonder onderbreking van de service.
Er kunnen situaties zijn waarin een sleutel wordt gemaakt met onmiddellijke activering. Een voorbeeld hiervan is wanneer de toepassing een tijd niet is gestart en alle sleutels in de sleutelring zijn verlopen. Als dit gebeurt, krijgt de sleutel een activeringsdatum van { now } zonder de normale activeringsvertraging van 2 dagen.
De standaardlevensduur van de sleutel is 90 dagen, hoewel dit kan worden geconfigureerd zoals in het volgende voorbeeld.
services.AddDataProtection()
// use 14-day lifetime instead of 90-day lifetime
.SetDefaultKeyLifetime(TimeSpan.FromDays(14));
Een beheerder kan ook het standaardsysteem wijzigen, hoewel een expliciete aanroep van SetDefaultKeyLifetime
elk systeembreed beleid overschrijft. De standaardsleutellevensduur mag niet korter zijn dan 7 dagen.
Automatisch vernieuwen van sleutelring
Wanneer het gegevensbeveiligingssysteem initialiseert, wordt de sleutelring uit de onderliggende opslagplaats gelezen en in het geheugen opgeslagen. Met deze cache kunnen de bewerkingen Beschermen en Debeschermen doorgaan zonder de achterliggende opslag te raken. Het systeem controleert automatisch de back-upopslag op wijzigingen ongeveer om de 24 uur of wanneer de huidige standaardsleutel verloopt, afhankelijk van wat het eerst komt.
Waarschuwing
Ontwikkelaars moeten de sleutelbeheer-API's zelden (indien ooit) rechtstreeks gebruiken. Het systeem voor gegevensbeveiliging voert automatisch sleutelbeheer uit zoals hierboven beschreven.
Het systeem voor gegevensbeveiliging bevat een interface IKeyManager
die kan worden gebruikt om de sleutelring te controleren en te wijzigen. Het DI-systeem dat het exemplaar van IDataProtectionProvider
heeft geleverd, kan ook een exemplaar van IKeyManager
bieden voor uw verbruik. U kunt de IKeyManager
ook rechtstreeks uit de IServiceProvider
halen, zoals in het onderstaande voorbeeld.
Elke bewerking die de sleutelring wijzigt (het expliciet maken van een nieuwe sleutel of het uitvoeren van een intrekking) maakt de cache in het geheugen ongeldig. De volgende aanroep van Protect
of Unprotect
zorgt ervoor dat het systeem voor gegevensbeveiliging de sleutelring opnieuw kan lezen en de cache opnieuw maakt.
In het onderstaande voorbeeld ziet u hoe u de IKeyManager
-interface gebruikt om de sleutelring te inspecteren en te manipuleren, waaronder het intrekken van bestaande sleutels en het handmatig genereren van een nieuwe sleutel.
using System;
using System.IO;
using System.Threading;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main(string[] args)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection()
// point at a specific folder and use DPAPI to encrypt keys
.PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys"))
.ProtectKeysWithDpapi();
var services = serviceCollection.BuildServiceProvider();
// perform a protect operation to force the system to put at least
// one key in the key ring
services.GetDataProtector("Sample.KeyManager.v1").Protect("payload");
Console.WriteLine("Performed a protect operation.");
Thread.Sleep(2000);
// get a reference to the key manager
var keyManager = services.GetService<IKeyManager>();
// list all keys in the key ring
var allKeys = keyManager.GetAllKeys();
Console.WriteLine($"The key ring contains {allKeys.Count} key(s).");
foreach (var key in allKeys)
{
Console.WriteLine($"Key {key.KeyId:B}: Created = {key.CreationDate:u}, IsRevoked = {key.IsRevoked}");
}
// revoke all keys in the key ring
keyManager.RevokeAllKeys(DateTimeOffset.Now, reason: "Revocation reason here.");
Console.WriteLine("Revoked all existing keys.");
// add a new key to the key ring with immediate activation and a 1-month expiration
keyManager.CreateNewKey(
activationDate: DateTimeOffset.Now,
expirationDate: DateTimeOffset.Now.AddMonths(1));
Console.WriteLine("Added a new key.");
// list all keys in the key ring
allKeys = keyManager.GetAllKeys();
Console.WriteLine($"The key ring contains {allKeys.Count} key(s).");
foreach (var key in allKeys)
{
Console.WriteLine($"Key {key.KeyId:B}: Created = {key.CreationDate:u}, IsRevoked = {key.IsRevoked}");
}
}
}
/*
* SAMPLE OUTPUT
*
* Performed a protect operation.
* The key ring contains 1 key(s).
* Key {1b948618-be1f-440b-b204-64ff5a152552}: Created = 2015-03-18 22:20:49Z, IsRevoked = False
* Revoked all existing keys.
* Added a new key.
* The key ring contains 2 key(s).
* Key {1b948618-be1f-440b-b204-64ff5a152552}: Created = 2015-03-18 22:20:49Z, IsRevoked = True
* Key {2266fc40-e2fb-48c6-8ce2-5fde6b1493f7}: Created = 2015-03-18 22:20:51Z, IsRevoked = False
*/
Als u codeopmerkingen wilt zien die zijn vertaald naar andere talen dan Engels, laat het ons dan weten in dit GitHub-discussieprobleem.
Sleutelopslag
Het systeem voor gegevensbeveiliging heeft een heuristiek waarbij wordt geprobeerd om automatisch een geschikte sleutelopslaglocatie en versleuteling-at-rest-mechanisme te afleiden. Het sleutelpersistentiemechanisme kan ook worden geconfigureerd door de app-ontwikkelaar. In de volgende documenten worden de in-box implementaties van deze mechanismen besproken: