ASP.NET Core Veri Korumasını Yapılandırma

Data Protection sistemi başlatıldığında, işletim ortamına göre varsayılan ayarları uygular. Bu ayarlar tek bir makinede çalışan uygulamalar için uygundur. Ancak, bir geliştiricinin varsayılan ayarları değiştirmek isteyebileceği durumlar vardır:

  • Uygulama birden çok makineye yayılır.
  • Uyumluluk nedenleriyle.

Bu senaryolar için Veri Koruma sistemi zengin bir yapılandırma API'sini sunar.

Uyarı

Yapılandırma dosyalarına benzer şekilde, veri koruma anahtar halkası da uygun izinler kullanılarak korunmalıdır. Bekleyen anahtarları şifrelemeyi seçebilirsiniz, ancak bu, saldırganların yeni anahtarlar oluşturmasını engellemez. Sonuç olarak uygulamanızın güvenliği etkilenir. Data Protection ile yapılandırılan depolama konumunun erişimi, yapılandırma dosyalarını koruma yönteminize benzer şekilde uygulamanın kendisiyle sınırlı olmalıdır. Örneğin, anahtar halkanızı diskte depolamayı seçerseniz dosya sistemi izinlerini kullanın. Yalnızca web uygulamanızın çalıştığı kimliğin bu dizine okuma, yazma ve oluşturma erişimi olduğundan emin olun. Azure Blob Depolama kullanıyorsanız, yalnızca web uygulamasının blob deposunda yeni girdileri okuma, yazma veya oluşturma gibi özellikleri olmalıdır.

uzantı yöntemi AddDataProtection bir IDataProtectionBuilderdöndürür. IDataProtectionBuilder , Veri Koruma seçeneklerini yapılandırmak için birlikte zincirleyebileceğiniz uzantı yöntemlerini kullanıma sunar.

Bu makalede kullanılan Data Protection uzantıları için aşağıdaki NuGet paketleri gereklidir:

ProtectKeysWithAzureKeyVault

CLI kullanarak Azure'da oturum açın, örneğin:

az login

Anahtarları Azure Key Vault ile yönetmek için ile sistemini ProtectKeysWithAzureKeyVault yapılandırınProgram.cs. blobUriWithSasToken , anahtar dosyasının depolanması gereken tam URI'dir. URI, SAS belirtecini sorgu dizesi parametresi olarak içermelidir:

builder.Services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>"))
    .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

Bir uygulamanın KeyVault ile iletişim kurması ve kendisini yetkilendirmesi için Azure.Identity paketinin eklenmesi gerekir.

Anahtarlık depolama konumunu ayarlayın (örneğin, PersistKeysToAzureBlobStorage). Çağrı ProtectKeysWithAzureKeyVault , anahtar halkası depolama konumu da dahil olmak üzere otomatik veri koruma ayarlarını devre dışı bırakan bir IXmlEncryptor uyguladığından konum ayarlanmalıdır. Yukarıdaki örnek, anahtar halkasını kalıcı hale getirmek için Azure Blob Depolama kullanır. Daha fazla bilgi için bkz. Anahtar depolama sağlayıcıları: Azure Depolama. Anahtar halkasını PersistKeysToFileSystem ile yerel olarak da kalıcı hale ekleyebilirsiniz.

keyIdentifier, anahtar şifrelemesi için kullanılan anahtar kasası anahtar tanımlayıcısıdır. Örneğin, içinde adlı dataprotection anahtar kasasında contosokeyvault oluşturulan bir anahtarın anahtar tanımlayıcısı https://contosokeyvault.vault.azure.net/keys/dataprotection/vardır. Uygulamaya Anahtar kasasına Alma, Anahtarı Açma ve Anahtar Sarmalama izinlerini sağlayın.

ProtectKeysWithAzureKeyVault Aşırı:

Uygulama eski Azure paketlerini (Microsoft.AspNetCore.DataProtection.Azure Depolama ve Microsoft.AspNetCore.DataProtection.AzureKeyVault) kullanıyorsa, bu başvuruları kaldırmanızı ve Azure.Extensions.AspNetCore.DataProtection.Blobs ve Azure.Extensions.AspNetCore.DataProtection.Keys sürümüne yükseltmenizi öneririz. Bu paketler, yeni güncelleştirmelerin sağlandığı yerdir ve eski paketlerle ilgili bazı önemli güvenlik ve kararlılık sorunlarını giderir.

builder.Services.AddDataProtection()
    // This blob must already exist before the application is run
    .PersistKeysToAzureBlobStorage("<storageAccountConnectionString", "<containerName>", "<blobName>")
    // Removing this line below for an initial run will ensure the file is created correctly
    .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

PersistKeysToFileSystem

Anahtarları %LOCALAPPDATA% varsayılan konumu yerine bir UNC paylaşımında depolamak için, sistemi ile PersistKeysToFileSystemyapılandırın:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));

Uyarı

Anahtar kalıcılığı konumunu değiştirirseniz, DPAPI'nin uygun bir şifreleme mekanizması olup olmadığını bilmediğinden sistem artık bekleyen anahtarları otomatik olarak şifrelemez.

PersistKeysToDbContext

EntityFramework kullanarak bir veritabanında anahtarları depolamak için sistemi Microsoft.AspNetCore.DataProtection.EntityFrameworkCore paketiyle yapılandırın:

builder.Services.AddDataProtection()
    .PersistKeysToDbContext<SampleDbContext>();

Yukarıdaki kod anahtarları yapılandırılan veritabanında depolar. Kullanılan veritabanı bağlamı uygulaması IDataProtectionKeyContextgerekir. IDataProtectionKeyContext özelliğini kullanıma sunar DataProtectionKeys

public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } = null!;

Bu özellik anahtarların depolandığı tabloyu temsil eder. Tabloyu el ile veya Geçişler ile DbContext oluşturun. Daha fazla bilgi için bkz. DataProtectionKey.

ProtectKeysWith*

ProtectKeysWith* yapılandırma API'lerinden herhangi birini çağırarak sistemi bekleyen anahtarları koruyacak şekilde yapılandırabilirsiniz. Anahtarları unc paylaşımında depolayan ve bekleyen bu anahtarları belirli bir X.509 sertifikasıyla şifreleyen aşağıdaki örneği göz önünde bulundurun:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    .ProtectKeysWithCertificate(builder.Configuration["CertificateThumbprint"]);

dosyasına bir dosyadan yüklenen sertifika gibi bir sağlayabilirsiniz X509Certificate2ProtectKeysWithCertificate:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    .ProtectKeysWithCertificate(
        new X509Certificate2("certificate.pfx", builder.Configuration["CertificatePassword"]));

Yerleşik anahtar şifreleme mekanizmaları hakkında daha fazla örnek ve tartışma için bkz . Bekleyen Anahtar Şifrelemesi.

UnprotectKeysWithAnyCertificate

ile UnprotectKeysWithAnyCertificatebir dizi sertifika kullanarak sertifikaları döndürebilir ve bekleyen anahtarların X509Certificate2 şifresini çözebilirsiniz:

builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    .ProtectKeysWithCertificate(
        new X509Certificate2("certificate.pfx", builder.Configuration["CertificatePassword"]))
    .UnprotectKeysWithAnyCertificate(
        new X509Certificate2("certificate_1.pfx", builder.Configuration["CertificatePassword_1"]),
        new X509Certificate2("certificate_2.pfx", builder.Configuration["CertificatePassword_2"]));

SetDefaultKeyLifetime

Sistemi varsayılan 90 gün yerine 14 günlük bir anahtar ömrü kullanacak şekilde yapılandırmak için kullanın SetDefaultKeyLifetime:

builder.Services.AddDataProtection()
    .SetDefaultKeyLifetime(TimeSpan.FromDays(14));

SetApplicationName

Varsayılan olarak, Data Protection sistemi aynı fiziksel anahtar deposunu paylaşsalar bile uygulamaları içerik kök yollarına göre birbirinden ayırır. Bu yalıtım, uygulamaların birbirlerinin korumalı yüklerini anlamasını engeller.

Korumalı yükleri uygulamalar arasında paylaşmak için:

  • Her uygulamada aynı değerle yapılandırın SetApplicationName .
  • Uygulamalar genelinde Data Protection API yığınının aynı sürümünü kullanın. Uygulamaların proje dosyalarında aşağıdakilerden birini gerçekleştirin:
    • Microsoft.AspNetCore.App meta paketi aracılığıyla aynı paylaşılan çerçeve sürümüne başvurun.
    • Aynı Data Protection paketi sürümüne başvurun.
builder.Services.AddDataProtection()
    .SetApplicationName("<sharedApplicationName>");

SetApplicationName dahili olarak ayarlar DataProtectionOptions.ApplicationDiscriminator. Sorun giderme amacıyla, çerçeve tarafından ayrıştırıcıya atanan değer, yerleşik olarak oluşturulduktan sonra yerleştirilen aşağıdaki kodla günlüğe WebApplicationProgram.cskaydedilebilir:

var discriminator = app.Services.GetRequiredService<IOptions<DataProtectionOptions>>()
    .Value.ApplicationDiscriminator;
app.Logger.LogInformation("ApplicationDiscriminator: {ApplicationDiscriminator}", discriminator);

Ayırıcının nasıl kullanıldığı hakkında daha fazla bilgi için bu makalenin devamında yer alan aşağıdaki bölümlere bakın:

Uyarı

.NET 6'da içerik WebApplicationBuilder kök yolunu ile DirectorySeparatorCharbitmesi için normalleştirir. Örneğin, Windows'ta içerik kök yolu ile linux /üzerinde biter\. Diğer konaklar yolu normalleştirmez. veya WebHostBuilder uygulamasından HostBuilder geçiş yapılan uygulamaların çoğu sonlandırıcıya DirectorySeparatorCharsahip olmayacağından aynı uygulama adını paylaşmaz. Bu sorunu geçici olarak çözmek için dizin ayırıcı karakterini kaldırın ve uygulama adını aşağıdaki kodda gösterildiği gibi el ile ayarlayın:

using Microsoft.AspNetCore.DataProtection;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);
var trimmedContentRootPath = builder.Environment.ContentRootPath.TrimEnd(Path.DirectorySeparatorChar);
builder.Services.AddDataProtection()
 .SetApplicationName(trimmedContentRootPath);
var app = builder.Build();

app.MapGet("/", () => Assembly.GetEntryAssembly()!.GetName().Name);

app.Run();

DisableAutomaticKeyGeneration

Bir uygulamanın süre sonu yaklaştıkça anahtarları otomatik olarak teslim etmelerini (yeni anahtarlar oluşturma) istemediğiniz bir senaryonuz olabilir. Bu senaryoya örnek olarak birincil/ikincil ilişkide ayarlanmış uygulamalar gösterilebilir. Burada anahtar yönetimi endişelerinden yalnızca birincil uygulama sorumludur ve ikincil uygulamalar yalnızca anahtar halkasının salt okunur bir görünümüne sahiptir. İkincil uygulamalar, ile sistemi DisableAutomaticKeyGenerationyapılandırarak anahtar halkasını salt okunur olarak değerlendirecek şekilde yapılandırılabilir:

builder.Services.AddDataProtection()
    .DisableAutomaticKeyGeneration();

Uygulama başına yalıtım

Data Protection sistemi bir ASP.NET Core konağı tarafından sağlandığında, bu uygulamalar aynı çalışan işlem hesabı altında çalışıyor olsa ve aynı ana anahtarlama malzemesini kullanıyor olsalar bile uygulamaları otomatik olarak birbirinden ayırır. Bu, System.Web öğesinden IsolateApps değiştiricisine <machineKey> benzer.

Yalıtım mekanizması, yerel makinedeki her uygulamayı benzersiz bir kiracı olarak dikkate alarak çalışır, bu nedenle IDataProtector belirli bir uygulamanın kökü otomatik olarak uygulama kimliğini ayrıştırıcı (ApplicationDiscriminator olarak) içerir. Uygulamanın benzersiz kimliği, uygulamanın fiziksel yoludur:

  • IIS'de barındırılan uygulamalar için benzersiz kimlik, uygulamanın IIS fiziksel yoludur. Bir uygulama bir web grubu ortamında dağıtılırsa, IIS ortamlarının web grubundaki tüm makinelerde benzer şekilde yapılandırıldığı varsayıldığında bu değer kararlıdır.
  • Sunucuda çalışan şirket içinde barındırılan Kestrel uygulamalar için benzersiz kimlik, disk üzerindeki uygulamanın fiziksel yoludur.

Benzersiz tanımlayıcı, hem tek tek uygulama hem de makinenin kendisi olmak üzere sıfırlamalara dayanacak şekilde tasarlanmıştır.

Bu yalıtım mekanizması, uygulamaların kötü amaçlı olmadığını varsayar. Kötü amaçlı bir uygulama her zaman aynı çalışan işlem hesabı altında çalışan diğer tüm uygulamaları etkileyebilir. Uygulamaların karşılıklı olarak güvenilmeyen paylaşılan bir barındırma ortamında, barındırma sağlayıcısı uygulamaların temel alınan anahtar depolarını ayırmak da dahil olmak üzere uygulamalar arasında işletim sistemi düzeyinde yalıtım sağlamak için adımlar atmalıdır.

Data Protection sistemi bir ASP.NET Core konağı tarafından sağlanmadıysa (örneğin, somut tür aracılığıyla DataProtectionProvider örneği oluşturursanız) uygulama yalıtımı varsayılan olarak devre dışı bırakılır. Uygulama yalıtımı devre dışı bırakıldığında, aynı anahtarlama malzemesi tarafından yedeklenen tüm uygulamalar, uygun amaçları sağladığı sürece yükleri paylaşabilir. Bu ortamda uygulama yalıtımı sağlamak için yapılandırma nesnesinde yöntemini çağırın SetApplicationName ve her uygulama için benzersiz bir ad sağlayın.

Veri Koruması ve uygulama yalıtımı

Uygulama yalıtımı için aşağıdaki noktaları göz önünde bulundurun:

  • Birden çok uygulama aynı anahtar deposuna işaret edildiğinde, uygulamaların aynı ana anahtar malzemesini paylaşması amaçlanır. Veri Koruması, anahtar kademesini paylaşan tüm uygulamaların bu anahtar kademedeki tüm öğelere erişebileceği varsayımıyla geliştirilmiştir. Uygulama benzersiz tanımlayıcısı, anahtar kademesi tarafından sağlanan anahtarlardan türetilen uygulamaya özgü anahtarları yalıtmak için kullanılır. Ek yalıtımı zorlamak için Azure KeyVault tarafından sağlananlar gibi öğe düzeyi izinlerinin kullanılmasını beklemez. Öğe düzeyi izinlerinin denenilmesi uygulama hataları oluşturur. Yerleşik uygulama yalıtımına güvenmek istemiyorsanız, uygulamalar arasında ayrı anahtar deposu konumları kullanılmalı ve paylaşılmamalıdır.

  • Uygulama ayırıcısı (ApplicationDiscriminator), farklı uygulamaların aynı ana anahtar malzemesini paylaşmasına izin vermek, ancak şifreleme yüklerini birbirinden ayrı tutmak için kullanılır. Uygulamaların birbirlerinin şifreleme yüklerini okuyabilmesi için, çağrılarak SetApplicationNameayarlanabilen aynı uygulama ayırıcısına sahip olmaları gerekir.

  • Bir uygulamanın güvenliği aşılırsa (örneğin, RCE saldırısıyla), bu uygulamanın erişebildiği tüm ana anahtar malzemelerinin de, bekleyen koruma durumundan bağımsız olarak gizliliği ihlal edilmiş olarak kabul edilmesi gerekir. Bu, iki uygulamanın aynı depoya işaret edilirse, farklı uygulama ayırıcıları kullansalar bile, birinin gizliliğinin aşılmasına işlevsel olarak her ikisinin de güvenliğinin aşılmasına eşdeğer olduğu anlamına gelir.

    Bu "işlevsel olarak her ikisinin de güvenliğinin aşılmasına eşdeğerdir" yan tümcesi, iki uygulama bekleyen anahtar koruması için farklı mekanizmalar kullansa bile tutar. Bu genellikle beklenen bir yapılandırma değildir. Bekleyen koruma mekanizması, bir saldırganın depoya okuma erişimi kazanması durumunda koruma sağlamak için tasarlanmıştır. Depoya yazma erişimi kazanan bir saldırgan (bir uygulama içinde kod yürütme izni almış olabilir) depolama alanına kötü amaçlı anahtarlar ekleyebilir. Veri Koruma sistemi, anahtar deposuna yazma erişimi kazanan bir saldırgana karşı kasıtlı olarak koruma sağlamaz.

  • Uygulamaların birbirinden gerçekten yalıtılmış kalması gerekiyorsa, farklı anahtar depoları kullanmalıdır. Bu doğal olarak "yalıtılmış" tanımından çıkar. Hepsinin birbirlerinin veri depolarına Okuma ve Yazma erişimi varsa uygulamalar yalıtılmaz .

UseCryptographicAlgorithms ile algoritmaları değiştirme

Veri Koruma yığını, yeni oluşturulan anahtarlar tarafından kullanılan varsayılan algoritmayı değiştirmenize olanak tanır. Bunu yapmanın en basit yolu, yapılandırma geri çağrısından çağırmaktır UseCryptographicAlgorithms :

builder.Services.AddDataProtection()
    .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });

Varsayılan EncryptionAlgorithm AES-256-CBC'dir ve varsayılan ValidationAlgorithm HMACSHA256. Varsayılan ilke, makine genelinde bir ilke aracılığıyla sistem yöneticisi tarafından ayarlanabilir, ancak açık bir çağrı UseCryptographicAlgorithms varsayılan ilkeyi geçersiz kılar.

Çağırma UseCryptographicAlgorithms , önceden tanımlanmış yerleşik bir listeden istenen algoritmayı belirtmenize olanak tanır. Algoritmanın uygulanması konusunda endişelenmeniz gerekmez. Yukarıdaki senaryoda, Veri Koruma sistemi Windows üzerinde çalışıyorsa AES'nin CNG uygulamasını kullanmayı dener. Aksi takdirde yönetilen sınıfa System.Security.Cryptography.Aes geri döner.

uygulamasına UseCustomCryptographicAlgorithmsyapılan bir çağrı aracılığıyla el ile belirtebilirsiniz.

Bahşiş

Algoritmaların değiştirilmesi, anahtar kademesindeki mevcut anahtarları etkilemez. Yalnızca yeni oluşturulan anahtarları etkiler.

Özel yönetilen algoritmaları belirtme

Özel yönetilen algoritmalar belirtmek için uygulama türlerine işaret eden bir ManagedAuthenticatedEncryptorConfiguration örnek oluşturun:

builder.Services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(new ManagedAuthenticatedEncryptorConfiguration
    {
        // A type that subclasses SymmetricAlgorithm
        EncryptionAlgorithmType = typeof(Aes),

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // A type that subclasses KeyedHashAlgorithm
        ValidationAlgorithmType = typeof(HMACSHA256)
    });

Genellikle *Tür özellikleri, ve KeyedHashAlgorithm'nin somut, örneklenebilir (genel parametresiz bir ctor aracılığıyla) uygulamalarına SymmetricAlgorithm işaret etmelidir, ancak sistem kolaylık sağlamak için gibi typeof(Aes) bazı değerleri özel olarak gösterir.

Dekont

SymmetricAlgorithm'in anahtar uzunluğu ≥ 128 bit ve blok boyutu ≥ 64 bit olmalıdır ve PKCS #7 doldurma ile CBC modu şifrelemesini desteklemelidir. KeyedHashAlgorithm değeri = 128 bit özet boyutuna >sahip olmalı ve karma algoritmasının özet uzunluğuna eşit uzunluk anahtarlarını desteklemelidir. KeyedHashAlgorithm'in HMAC olması kesinlikle gerekli değildir.

Özel Windows CNG algoritmaları belirtme

HMAC doğrulaması ile CBC modu şifrelemesi kullanarak özel bir Windows CNG algoritması belirtmek için algoritma bilgilerini içeren bir CngCbcAuthenticatedEncryptorConfiguration örnek oluşturun:

builder.Services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(new CngCbcAuthenticatedEncryptorConfiguration
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // Passed to BCryptOpenAlgorithmProvider
        HashAlgorithm = "SHA256",
        HashAlgorithmProvider = null
    });

Dekont

Simetrik blok şifreleme algoritmasının anahtar uzunluğu >= 128 bit, blok boyutu >= 64 bit olmalı ve PKCS #7 doldurma ile CBC modu şifrelemesini desteklemelidir. Karma algoritmanın >özet boyutu = 128 bit olmalıdır ve BCRYPT_ALG_HANDLE_HMAC_FLAG bayrağıyla açılması desteklenmelidir. *Sağlayıcı özellikleri, belirtilen algoritma için varsayılan sağlayıcıyı kullanmak üzere null olarak ayarlanabilir. Daha fazla bilgi için BCryptOpenAlgorithmProvider belgelerine bakın.

Doğrulama ile Galois/Sayaç Modu şifrelemesi kullanarak özel bir Windows CNG algoritması belirtmek için algoritma bilgilerini içeren bir CngGcmAuthenticatedEncryptorConfiguration örnek oluşturun:

builder.Services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(new CngGcmAuthenticatedEncryptorConfiguration
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

Dekont

Simetrik blok şifreleme algoritmasının anahtar uzunluğu >= 128 bit, blok boyutu tam olarak 128 bit olmalıdır ve GCM şifrelemesini desteklemelidir. Belirtilen algoritma için EncryptionAlgorithmProvider varsayılan sağlayıcıyı kullanmak üzere özelliğini null olarak ayarlayabilirsiniz. Daha fazla bilgi için BCryptOpenAlgorithmProvider belgelerine bakın.

Diğer özel algoritmaları belirtme

Birinci sınıf API olarak sunulmasa da, Veri Koruma sistemi neredeyse her tür algoritmanın belirtilmesine izin verecek kadar genişletilebilir. Örneğin, donanım güvenlik modülünde (HSM) bulunan tüm anahtarları tutmak ve çekirdek şifreleme ve şifre çözme yordamlarının özel bir uygulamasını sağlamak mümkündür. Daha fazla bilgi için bkz IAuthenticatedEncryptor. Çekirdek şifreleme genişletilebilirliği.

Docker kapsayıcısında barındırırken anahtarları kalıcı hale getirme

Docker kapsayıcısında barındırılırken anahtarlar aşağıdakilerden herhangi biri içinde tutulmalıdır:

Redis ile kalıcı anahtarlar

Anahtarları depolamak için yalnızca Redis Veri Kalıcılığını destekleyen Redis sürümleri kullanılmalıdır. Azure Blob depolama kalıcıdır ve anahtarları depolamak için kullanılabilir. Daha fazla bilgi için bu GitHub konusuna bakın.

DataProtection Günlüğe Kaydetme

Sorunu tanılamaya yardımcı olmak için DataProtection'ın düzey günlüğünü etkinleştirin Information . Aşağıdaki appsettings.json dosya DataProtection API'sinin bilgi günlüğünü etkinleştirir:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.DataProtection": "Information"
    }
  },
  "AllowedHosts": "*"
}

Günlüğe kaydetme hakkında daha fazla bilgi için bkz . .NET Core ve ASP.NET Core'da günlüğe kaydetme.

Ek kaynaklar

Data Protection sistemi başlatıldığında, işletim ortamına göre varsayılan ayarları uygular. Bu ayarlar tek bir makinede çalışan uygulamalar için uygundur. Ancak, bir geliştiricinin varsayılan ayarları değiştirmek isteyebileceği durumlar vardır:

  • Uygulama birden çok makineye yayılır.
  • Uyumluluk nedenleriyle.

Bu senaryolar için Veri Koruma sistemi zengin bir yapılandırma API'sini sunar.

Uyarı

Yapılandırma dosyalarına benzer şekilde, veri koruma anahtar halkası da uygun izinler kullanılarak korunmalıdır. Bekleyen anahtarları şifrelemeyi seçebilirsiniz, ancak bu, saldırganların yeni anahtarlar oluşturmasını engellemez. Sonuç olarak uygulamanızın güvenliği etkilenir. Data Protection ile yapılandırılan depolama konumunun erişimi, yapılandırma dosyalarını koruma yönteminize benzer şekilde uygulamanın kendisiyle sınırlı olmalıdır. Örneğin, anahtar halkanızı diskte depolamayı seçerseniz dosya sistemi izinlerini kullanın. Yalnızca web uygulamanızın çalıştığı kimliğin bu dizine okuma, yazma ve oluşturma erişimi olduğundan emin olun. Azure Blob Depolama kullanıyorsanız, yalnızca web uygulamasının blob deposunda yeni girdileri okuma, yazma veya oluşturma gibi özellikleri olmalıdır.

uzantı yöntemi AddDataProtection bir IDataProtectionBuilderdöndürür. IDataProtectionBuilder , Veri Koruma seçeneklerini yapılandırmak için birlikte zincirleyebileceğiniz uzantı yöntemlerini kullanıma sunar.

Bu makalede kullanılan Data Protection uzantıları için aşağıdaki NuGet paketleri gereklidir:

ProtectKeysWithAzureKeyVault

CLI kullanarak Azure'da oturum açın, örneğin:

az login

Anahtarları Azure Key Vault'ta depolamak için ile sınıfını ProtectKeysWithAzureKeyVaultStartup yapılandırın. blobUriWithSasToken , anahtar dosyasının depolanması gereken tam URI'dir. URI, SAS belirtecini sorgu dizesi parametresi olarak içermelidir:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>"))
        .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());
}

Bir uygulamanın KeyVault ile iletişim kurması ve kendisini yetkilendirmesi için Azure.Identity paketinin eklenmesi gerekir.

Anahtarlık depolama konumunu ayarlayın (örneğin, PersistKeysToAzureBlobStorage). Çağrı ProtectKeysWithAzureKeyVault , anahtar halkası depolama konumu da dahil olmak üzere otomatik veri koruma ayarlarını devre dışı bırakan bir IXmlEncryptor uyguladığından konum ayarlanmalıdır. Yukarıdaki örnek, anahtar halkasını kalıcı hale getirmek için Azure Blob Depolama kullanır. Daha fazla bilgi için bkz. Anahtar depolama sağlayıcıları: Azure Depolama. Anahtar halkasını PersistKeysToFileSystem ile yerel olarak da kalıcı hale ekleyebilirsiniz.

keyIdentifier, anahtar şifrelemesi için kullanılan anahtar kasası anahtar tanımlayıcısıdır. Örneğin, içinde adlı dataprotection anahtar kasasında contosokeyvault oluşturulan bir anahtarın anahtar tanımlayıcısı https://contosokeyvault.vault.azure.net/keys/dataprotection/vardır. Uygulamaya Anahtar kasasına Alma, Anahtarı Açma ve Anahtar Sarmalama izinlerini sağlayın.

ProtectKeysWithAzureKeyVault Aşırı:

Uygulama eski Azure paketlerini (Microsoft.AspNetCore.DataProtection.Azure Depolama ve Microsoft.AspNetCore.DataProtection.AzureKeyVault) kullanıyorsa, bu başvuruları kaldırmanızı ve Azure.Extensions.AspNetCore.DataProtection.Blobs ve Azure.Extensions.AspNetCore.DataProtection.Keys sürümüne yükseltmenizi öneririz. Bu paketler, yeni güncelleştirmelerin sağlandığı yerdir ve eski paketlerle ilgili bazı önemli güvenlik ve kararlılık sorunlarını giderir.

services.AddDataProtection()
    //This blob must already exist before the application is run
    .PersistKeysToAzureBlobStorage("<storage account connection string", "<key store container name>", "<key store blob name>")
    //Removing this line below for an initial run will ensure the file is created correctly
    .ProtectKeysWithAzureKeyVault(new Uri("<keyIdentifier>"), new DefaultAzureCredential());

PersistKeysToFileSystem

Anahtarları %LOCALAPPDATA% varsayılan konumu yerine bir UNC paylaşımında depolamak için, sistemi ile PersistKeysToFileSystemyapılandırın:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"));
}

Uyarı

Anahtar kalıcılığı konumunu değiştirirseniz, DPAPI'nin uygun bir şifreleme mekanizması olup olmadığını bilmediğinden sistem artık bekleyen anahtarları otomatik olarak şifrelemez.

PersistKeysToDbContext

EntityFramework kullanarak bir veritabanında anahtarları depolamak için sistemi Microsoft.AspNetCore.DataProtection.EntityFrameworkCore paketiyle yapılandırın:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToDbContext<DbContext>()
}

Yukarıdaki kod anahtarları yapılandırılan veritabanında depolar. Kullanılan veritabanı bağlamı uygulaması IDataProtectionKeyContextgerekir. IDataProtectionKeyContext özelliğini kullanıma sunar DataProtectionKeys

public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }

Bu özellik anahtarların depolandığı tabloyu temsil eder. Tabloyu el ile veya Geçişler ile DbContext oluşturun. Daha fazla bilgi için bkz. DataProtectionKey.

ProtectKeysWith*

ProtectKeysWith* yapılandırma API'lerinden herhangi birini çağırarak sistemi bekleyen anahtarları koruyacak şekilde yapılandırabilirsiniz. Anahtarları unc paylaşımında depolayan ve bekleyen bu anahtarları belirli bir X.509 sertifikasıyla şifreleyen aşağıdaki örneği göz önünde bulundurun:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(Configuration["Thumbprint"]);
}

dosyasına bir dosyadan yüklenen sertifika gibi bir sağlayabilirsiniz X509Certificate2ProtectKeysWithCertificate:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(
            new X509Certificate2("certificate.pfx", Configuration["Thumbprint"]));
}

Yerleşik anahtar şifreleme mekanizmaları hakkında daha fazla örnek ve tartışma için bkz . Bekleyen Anahtar Şifrelemesi.

UnprotectKeysWithAnyCertificate

ile UnprotectKeysWithAnyCertificatebir dizi sertifika kullanarak sertifikaları döndürebilir ve bekleyen anahtarların X509Certificate2 şifresini çözebilirsiniz:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
        .ProtectKeysWithCertificate(
            new X509Certificate2("certificate.pfx", Configuration["MyPasswordKey"));
        .UnprotectKeysWithAnyCertificate(
            new X509Certificate2("certificate_old_1.pfx", Configuration["MyPasswordKey_1"]),
            new X509Certificate2("certificate_old_2.pfx", Configuration["MyPasswordKey_2"]));
}

SetDefaultKeyLifetime

Sistemi varsayılan 90 gün yerine 14 günlük bir anahtar ömrü kullanacak şekilde yapılandırmak için kullanın SetDefaultKeyLifetime:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetDefaultKeyLifetime(TimeSpan.FromDays(14));
}

SetApplicationName

Varsayılan olarak, Data Protection sistemi aynı fiziksel anahtar deposunu paylaşsalar bile uygulamaları içerik kök yollarına göre birbirinden ayırır. Bu yalıtım, uygulamaların birbirlerinin korumalı yüklerini anlamasını engeller.

Korumalı yükleri uygulamalar arasında paylaşmak için:

  • Her uygulamada aynı değerle yapılandırın SetApplicationName .
  • Uygulamalar genelinde Data Protection API yığınının aynı sürümünü kullanın. Uygulamaların proje dosyalarında aşağıdakilerden birini gerçekleştirin:
    • Microsoft.AspNetCore.App meta paketi aracılığıyla aynı paylaşılan çerçeve sürümüne başvurun.
    • Aynı Data Protection paketi sürümüne başvurun.
public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .SetApplicationName("shared app name");
}

SetApplicationName dahili olarak ayarlar DataProtectionOptions.ApplicationDiscriminator. Ayırıcının nasıl kullanıldığı hakkında daha fazla bilgi için bu makalenin devamında yer alan aşağıdaki bölümlere bakın:

DisableAutomaticKeyGeneration

Bir uygulamanın süre sonu yaklaştıkça anahtarları otomatik olarak teslim etmelerini (yeni anahtarlar oluşturma) istemediğiniz bir senaryonuz olabilir. Bu senaryoya örnek olarak birincil/ikincil ilişkide ayarlanmış uygulamalar gösterilebilir. Burada anahtar yönetimi endişelerinden yalnızca birincil uygulama sorumludur ve ikincil uygulamalar yalnızca anahtar halkasının salt okunur bir görünümüne sahiptir. İkincil uygulamalar, ile sistemi DisableAutomaticKeyGenerationyapılandırarak anahtar halkasını salt okunur olarak değerlendirecek şekilde yapılandırılabilir:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDataProtection()
        .DisableAutomaticKeyGeneration();
}

Uygulama başına yalıtım

Data Protection sistemi bir ASP.NET Core konağı tarafından sağlandığında, bu uygulamalar aynı çalışan işlem hesabı altında çalışıyor olsa ve aynı ana anahtarlama malzemesini kullanıyor olsalar bile uygulamaları otomatik olarak birbirinden ayırır. Bu, System.Web öğesinden IsolateApps değiştiricisine <machineKey> benzer.

Yalıtım mekanizması, yerel makinedeki her uygulamayı benzersiz bir kiracı olarak dikkate alarak çalışır, bu nedenle IDataProtector belirli bir uygulamanın kökü otomatik olarak uygulama kimliğini ayrıştırıcı (ApplicationDiscriminator olarak) içerir. Uygulamanın benzersiz kimliği, uygulamanın fiziksel yoludur:

  • IIS'de barındırılan uygulamalar için benzersiz kimlik, uygulamanın IIS fiziksel yoludur. Bir uygulama bir web grubu ortamında dağıtılırsa, IIS ortamlarının web grubundaki tüm makinelerde benzer şekilde yapılandırıldığı varsayıldığında bu değer kararlıdır.
  • Sunucuda çalışan şirket içinde barındırılan Kestrel uygulamalar için benzersiz kimlik, disk üzerindeki uygulamanın fiziksel yoludur.

Benzersiz tanımlayıcı, hem tek tek uygulama hem de makinenin kendisi olmak üzere sıfırlamalara dayanacak şekilde tasarlanmıştır.

Bu yalıtım mekanizması, uygulamaların kötü amaçlı olmadığını varsayar. Kötü amaçlı bir uygulama her zaman aynı çalışan işlem hesabı altında çalışan diğer tüm uygulamaları etkileyebilir. Uygulamaların karşılıklı olarak güvenilmeyen paylaşılan bir barındırma ortamında, barındırma sağlayıcısı uygulamaların temel alınan anahtar depolarını ayırmak da dahil olmak üzere uygulamalar arasında işletim sistemi düzeyinde yalıtım sağlamak için adımlar atmalıdır.

Data Protection sistemi bir ASP.NET Core konağı tarafından sağlanmadıysa (örneğin, somut tür aracılığıyla DataProtectionProvider örneği oluşturursanız) uygulama yalıtımı varsayılan olarak devre dışı bırakılır. Uygulama yalıtımı devre dışı bırakıldığında, aynı anahtarlama malzemesi tarafından yedeklenen tüm uygulamalar, uygun amaçları sağladığı sürece yükleri paylaşabilir. Bu ortamda uygulama yalıtımı sağlamak için yapılandırma nesnesinde SetApplicationName yöntemini çağırın ve her uygulama için benzersiz bir ad sağlayın.

Veri Koruması ve uygulama yalıtımı

Uygulama yalıtımı için aşağıdaki noktaları göz önünde bulundurun:

  • Birden çok uygulama aynı anahtar deposuna işaret edildiğinde, uygulamaların aynı ana anahtar malzemesini paylaşması amaçlanır. Veri Koruması, anahtar kademesini paylaşan tüm uygulamaların bu anahtar kademedeki tüm öğelere erişebileceği varsayımıyla geliştirilmiştir. Uygulama benzersiz tanımlayıcısı, anahtar kademesi tarafından sağlanan anahtarlardan türetilen uygulamaya özgü anahtarları yalıtmak için kullanılır. Ek yalıtımı zorlamak için Azure KeyVault tarafından sağlananlar gibi öğe düzeyi izinlerinin kullanılmasını beklemez. Öğe düzeyi izinlerinin denenilmesi uygulama hataları oluşturur. Yerleşik uygulama yalıtımına güvenmek istemiyorsanız, uygulamalar arasında ayrı anahtar deposu konumları kullanılmalı ve paylaşılmamalıdır.

  • Uygulama ayırıcısı (ApplicationDiscriminator), farklı uygulamaların aynı ana anahtar malzemesini paylaşmasına izin vermek, ancak şifreleme yüklerini birbirinden ayrı tutmak için kullanılır. Uygulamaların birbirlerinin şifreleme yüklerini okuyabilmesi için, çağrılarak SetApplicationNameayarlanabilen aynı uygulama ayırıcısına sahip olmaları gerekir.

  • Bir uygulamanın güvenliği aşılırsa (örneğin, RCE saldırısıyla), bu uygulamanın erişebildiği tüm ana anahtar malzemelerinin de, bekleyen koruma durumundan bağımsız olarak gizliliği ihlal edilmiş olarak kabul edilmesi gerekir. Bu, iki uygulamanın aynı depoya işaret edilirse, farklı uygulama ayırıcıları kullansalar bile, birinin gizliliğinin aşılmasına işlevsel olarak her ikisinin de güvenliğinin aşılmasına eşdeğer olduğu anlamına gelir.

    Bu "işlevsel olarak her ikisinin de güvenliğinin aşılmasına eşdeğerdir" yan tümcesi, iki uygulama bekleyen anahtar koruması için farklı mekanizmalar kullansa bile tutar. Bu genellikle beklenen bir yapılandırma değildir. Bekleyen koruma mekanizması, bir saldırganın depoya okuma erişimi kazanması durumunda koruma sağlamak için tasarlanmıştır. Depoya yazma erişimi kazanan bir saldırgan (bir uygulama içinde kod yürütme izni almış olabilir) depolama alanına kötü amaçlı anahtarlar ekleyebilir. Veri Koruma sistemi, anahtar deposuna yazma erişimi kazanan bir saldırgana karşı kasıtlı olarak koruma sağlamaz.

  • Uygulamaların birbirinden gerçekten yalıtılmış kalması gerekiyorsa, farklı anahtar depoları kullanmalıdır. Bu doğal olarak "yalıtılmış" tanımından çıkar. Hepsinin birbirlerinin veri depolarına Okuma ve Yazma erişimi varsa uygulamalar yalıtılmaz .

UseCryptographicAlgorithms ile algoritmaları değiştirme

Veri Koruma yığını, yeni oluşturulan anahtarlar tarafından kullanılan varsayılan algoritmayı değiştirmenize olanak tanır. Bunu yapmanın en basit yolu, yapılandırma geri çağrısından çağırmaktır UseCryptographicAlgorithms :

services.AddDataProtection()
    .UseCryptographicAlgorithms(
        new AuthenticatedEncryptorConfiguration()
    {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });

Varsayılan EncryptionAlgorithm AES-256-CBC'dir ve varsayılan ValidationAlgorithm HMACSHA256. Varsayılan ilke, makine genelinde bir ilke aracılığıyla sistem yöneticisi tarafından ayarlanabilir, ancak açık bir çağrı UseCryptographicAlgorithms varsayılan ilkeyi geçersiz kılar.

Çağırma UseCryptographicAlgorithms , önceden tanımlanmış yerleşik bir listeden istenen algoritmayı belirtmenize olanak tanır. Algoritmanın uygulanması konusunda endişelenmeniz gerekmez. Yukarıdaki senaryoda, Veri Koruma sistemi Windows üzerinde çalışıyorsa AES'nin CNG uygulamasını kullanmayı dener. Aksi takdirde yönetilen sınıfa System.Security.Cryptography.Aes geri döner.

uygulamasına UseCustomCryptographicAlgorithmsyapılan bir çağrı aracılığıyla el ile belirtebilirsiniz.

Bahşiş

Algoritmaların değiştirilmesi, anahtar kademesindeki mevcut anahtarları etkilemez. Yalnızca yeni oluşturulan anahtarları etkiler.

Özel yönetilen algoritmaları belirtme

Özel yönetilen algoritmalar belirtmek için uygulama türlerine işaret eden bir ManagedAuthenticatedEncryptorConfiguration örnek oluşturun:

serviceCollection.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new ManagedAuthenticatedEncryptorConfiguration()
    {
        // A type that subclasses SymmetricAlgorithm
        EncryptionAlgorithmType = typeof(Aes),

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // A type that subclasses KeyedHashAlgorithm
        ValidationAlgorithmType = typeof(HMACSHA256)
    });

Genellikle *Tür özellikleri, ve KeyedHashAlgorithm'nin somut, örneklenebilir (genel parametresiz bir ctor aracılığıyla) uygulamalarına SymmetricAlgorithm işaret etmelidir, ancak sistem kolaylık sağlamak için gibi typeof(Aes) bazı değerleri özel olarak gösterir.

Dekont

SymmetricAlgorithm'in anahtar uzunluğu ≥ 128 bit ve blok boyutu ≥ 64 bit olmalıdır ve PKCS #7 doldurma ile CBC modu şifrelemesini desteklemelidir. KeyedHashAlgorithm değeri = 128 bit özet boyutuna >sahip olmalı ve karma algoritmasının özet uzunluğuna eşit uzunluk anahtarlarını desteklemelidir. KeyedHashAlgorithm'in HMAC olması kesinlikle gerekli değildir.

Özel Windows CNG algoritmaları belirtme

HMAC doğrulaması ile CBC modu şifrelemesi kullanarak özel bir Windows CNG algoritması belirtmek için algoritma bilgilerini içeren bir CngCbcAuthenticatedEncryptorConfiguration örnek oluşturun:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngCbcAuthenticatedEncryptorConfiguration()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256,

        // Passed to BCryptOpenAlgorithmProvider
        HashAlgorithm = "SHA256",
        HashAlgorithmProvider = null
    });

Dekont

Simetrik blok şifreleme algoritmasının anahtar uzunluğu >= 128 bit, blok boyutu >= 64 bit olmalı ve PKCS #7 doldurma ile CBC modu şifrelemesini desteklemelidir. Karma algoritmanın >özet boyutu = 128 bit olmalıdır ve BCRYPT_ALG_HANDLE_HMAC_FLAG bayrağıyla açılması desteklenmelidir. *Sağlayıcı özellikleri, belirtilen algoritma için varsayılan sağlayıcıyı kullanmak üzere null olarak ayarlanabilir. Daha fazla bilgi için BCryptOpenAlgorithmProvider belgelerine bakın.

Doğrulama ile Galois/Sayaç Modu şifrelemesi kullanarak özel bir Windows CNG algoritması belirtmek için algoritma bilgilerini içeren bir CngGcmAuthenticatedEncryptorConfiguration örnek oluşturun:

services.AddDataProtection()
    .UseCustomCryptographicAlgorithms(
        new CngGcmAuthenticatedEncryptorConfiguration()
    {
        // Passed to BCryptOpenAlgorithmProvider
        EncryptionAlgorithm = "AES",
        EncryptionAlgorithmProvider = null,

        // Specified in bits
        EncryptionAlgorithmKeySize = 256
    });

Dekont

Simetrik blok şifreleme algoritmasının anahtar uzunluğu >= 128 bit, blok boyutu tam olarak 128 bit olmalıdır ve GCM şifrelemesini desteklemelidir. Belirtilen algoritma için EncryptionAlgorithmProvider varsayılan sağlayıcıyı kullanmak üzere özelliğini null olarak ayarlayabilirsiniz. Daha fazla bilgi için BCryptOpenAlgorithmProvider belgelerine bakın.

Diğer özel algoritmaları belirtme

Birinci sınıf API olarak sunulmasa da, Veri Koruma sistemi neredeyse her tür algoritmanın belirtilmesine izin verecek kadar genişletilebilir. Örneğin, donanım güvenlik modülünde (HSM) bulunan tüm anahtarları tutmak ve çekirdek şifreleme ve şifre çözme yordamlarının özel bir uygulamasını sağlamak mümkündür. Daha fazla bilgi için bkz IAuthenticatedEncryptor. Çekirdek şifreleme genişletilebilirliği.

Docker kapsayıcısında barındırırken anahtarları kalıcı hale getirme

Docker kapsayıcısında barındırılırken anahtarlar aşağıdakilerden herhangi biri içinde tutulmalıdır:

Redis ile kalıcı anahtarlar

Anahtarları depolamak için yalnızca Redis Veri Kalıcılığını destekleyen Redis sürümleri kullanılmalıdır. Azure Blob depolama kalıcıdır ve anahtarları depolamak için kullanılabilir. Daha fazla bilgi için bu GitHub konusuna bakın.

DataProtection Günlüğe Kaydetme

Sorunu tanılamaya yardımcı olmak için DataProtection'ın düzey günlüğünü etkinleştirin Information . Aşağıdaki appsettings.json dosya DataProtection API'sinin bilgi günlüğünü etkinleştirir:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.DataProtection": "Information"
    }
  }
}

Günlüğe kaydetme hakkında daha fazla bilgi için bkz . .NET Core ve ASP.NET Core'da günlüğe kaydetme.

Ek kaynaklar