Bagikan melalui


Ekstensibilitas manajemen utama di ASP.NET Core

Baca bagian manajemen kunci sebelum membaca bagian ini, karena menjelaskan beberapa konsep mendasar di balik API ini.

Peringatan: Jenis yang mengimplementasikan salah satu antarmuka berikut harus aman untuk beberapa pemanggil.

Tombol

Antarmuka IKey adalah representasi dasar kunci dalam cryptosystem. Istilah kunci digunakan di sini dalam arti abstrak, bukan dalam arti harfiah "materi kunci kriptografi". Kunci memiliki properti berikut:

  • Tanggal aktivasi, pembuatan, dan kedaluwarsa

  • Status pencabutan

  • Pengidentifikasi kunci (GUID)

Selain itu, IKey mengekspos metode yang dapat digunakan untuk membuat instans CreateEncryptor IAuthenticatedEncryptor yang terkait dengan kunci ini.

Selain itu, IKey mengekspos metode yang dapat digunakan untuk membuat instans CreateEncryptorInstance IAuthenticatedEncryptor yang terkait dengan kunci ini.

Catatan

Tidak ada API untuk mengambil materi kriptografi mentah dari IKey instans.

IKeyManager

Antarmuka IKeyManager mewakili objek yang bertanggung jawab atas penyimpanan kunci umum, pengambilan, dan manipulasi. Ini mengekspos tiga operasi tingkat tinggi:

  • Buat kunci baru dan pertahankan ke penyimpanan.

  • Dapatkan semua kunci dari penyimpanan.

  • Cabut satu atau beberapa kunci dan pertahankan informasi pencabutan ke penyimpanan.

Peringatan

Menulis adalah tugas yang IKeyManager sangat canggih, dan sebagian besar pengembang tidak boleh mencobanya. Sebaliknya, sebagian besar pengembang harus memanfaatkan fasilitas yang ditawarkan oleh kelas XmlKeyManager .

XmlKeyManager

Jenisnya XmlKeyManager adalah implementasi beton dalam kotak dari IKeyManager. Ini menyediakan beberapa fasilitas yang berguna, termasuk escrow kunci dan enkripsi kunci saat tidak aktif. Kunci dalam sistem ini direpresentasikan sebagai elemen XML (khususnya, XElement).

XmlKeyManager tergantung pada beberapa komponen lain selama memenuhi tugas-tugasnya:

  • AlgorithmConfiguration, yang menentukan algoritma yang digunakan oleh kunci baru.

  • IXmlRepository, yang mengontrol tempat kunci disimpan dalam penyimpanan.

  • IXmlEncryptor [opsional], yang memungkinkan mengenkripsi kunci tidak aktif.

  • IKeyEscrowSink [opsional], yang menyediakan layanan escrow utama.

  • IXmlRepository, yang mengontrol tempat kunci disimpan dalam penyimpanan.

  • IXmlEncryptor [opsional], yang memungkinkan mengenkripsi kunci tidak aktif.

  • IKeyEscrowSink [opsional], yang menyediakan layanan escrow utama.

Di bawah ini adalah diagram tingkat tinggi yang menunjukkan bagaimana komponen-komponen ini dikabelkan bersama-sama dalam XmlKeyManager.

Key Creation

Pembuatan Kunci / CreateNewKey

Dalam implementasi CreateNewKey, AlgorithmConfiguration komponen digunakan untuk membuat yang unik IAuthenticatedEncryptorDescriptor, yang kemudian diserialisasikan sebagai XML. Jika sink escrow kunci ada, XML mentah (tidak terenkripsi) disediakan ke sink untuk penyimpanan jangka panjang. XML yang tidak terenkripsi kemudian dijalankan melalui IXmlEncryptor (jika diperlukan) untuk menghasilkan dokumen XML terenkripsi. Dokumen terenkripsi ini dipertahankan ke penyimpanan jangka panjang melalui IXmlRepository. (Jika tidak IXmlEncryptor dikonfigurasi, dokumen yang tidak terenkripsi dipertahankan di IXmlRepository.)

Key Retrieval

Key Creation

Pembuatan Kunci / CreateNewKey

Dalam implementasi CreateNewKey, IAuthenticatedEncryptorConfiguration komponen digunakan untuk membuat yang unik IAuthenticatedEncryptorDescriptor, yang kemudian diserialisasikan sebagai XML. Jika sink escrow kunci ada, XML mentah (tidak terenkripsi) disediakan ke sink untuk penyimpanan jangka panjang. XML yang tidak terenkripsi kemudian dijalankan melalui IXmlEncryptor (jika diperlukan) untuk menghasilkan dokumen XML terenkripsi. Dokumen terenkripsi ini dipertahankan ke penyimpanan jangka panjang melalui IXmlRepository. (Jika tidak IXmlEncryptor dikonfigurasi, dokumen yang tidak terenkripsi dipertahankan di IXmlRepository.)

Key Retrieval

Pengambilan Kunci / GetAllKeys

Dalam implementasi GetAllKeys, dokumen XML yang mewakili kunci dan pencabutan dibaca dari yang mendasar IXmlRepository. Jika dokumen-dokumen ini dienkripsi, sistem akan secara otomatis mendekripsinya. XmlKeyManager membuat instans yang sesuai IAuthenticatedEncryptorDescriptorDeserializer untuk mendeserialisasi dokumen kembali ke dalam IAuthenticatedEncryptorDescriptor instans, yang kemudian dibungkus dalam instans individual IKey . Kumpulan IKey instans ini dikembalikan ke pemanggil.

Informasi lebih lanjut tentang elemen XML tertentu dapat ditemukan dalam dokumen format penyimpanan kunci.

IXmlRepository

Antarmuka IXmlRepository mewakili jenis yang dapat mempertahankan XML ke dan mengambil XML dari penyimpanan cadangan. Ini mengekspos dua API:

  • GetAllElements :IReadOnlyCollection<XElement>

  • StoreElement(XElement element, string friendlyName)

Implementasi tidak perlu mengurai IXmlRepository XML yang melewatinya. Mereka harus memperlakukan dokumen XML sebagai buram dan membiarkan lapisan yang lebih tinggi khawatir tentang menghasilkan dan mengurai dokumen.

Ada empat jenis beton bawaan yang mengimplementasikan IXmlRepository:

Lihat dokumen penyedia penyimpanan utama untuk informasi selengkapnya.

Mendaftarkan kustom IXmlRepository sesuai saat menggunakan penyimpanan backing yang berbeda (misalnya, Azure Table Storage).

Untuk mengubah seluruh aplikasi repositori default, daftarkan instans kustom IXmlRepository :

services.Configure<KeyManagementOptions>(options => options.XmlRepository = new MyCustomXmlRepository());
services.AddSingleton<IXmlRepository>(new MyCustomXmlRepository());

IXmlEncryptor

Antarmuka IXmlEncryptor mewakili jenis yang dapat mengenkripsi elemen XML teks biasa. Ini mengekspos satu API:

  • Encrypt(XElement plaintextElement) : EncryptedXmlInfo

Jika serial berisi IAuthenticatedEncryptorDescriptor elemen apa pun yang ditandai sebagai "memerlukan enkripsi", maka XmlKeyManager akan menjalankan elemen tersebut melalui metode yang Encrypt dikonfigurasiIXmlEncryptor, dan itu akan mempertahankan elemen yang disandikan daripada elemen teks biasa ke IXmlRepository. Output metode Encrypt adalah EncryptedXmlInfo objek. Objek ini adalah pembungkus yang berisi enciphered XElement yang dihasilkan dan Jenis yang mewakili IXmlDecryptor yang dapat digunakan untuk menguraikan elemen yang sesuai.

Ada empat jenis beton bawaan yang mengimplementasikan IXmlEncryptor:

Lihat dokumen enkripsi kunci saat tidak aktif untuk informasi selengkapnya.

Untuk mengubah mekanisme key-encryption-at-rest default di seluruh aplikasi, daftarkan instans kustom IXmlEncryptor :

services.Configure<KeyManagementOptions>(options => options.XmlEncryptor = new MyCustomXmlEncryptor());
services.AddSingleton<IXmlEncryptor>(new MyCustomXmlEncryptor());

IXmlDecryptor

Antarmuka IXmlDecryptor mewakili jenis yang tahu cara mendekripsi XElement yang dicipta melalui IXmlEncryptor. Ini mengekspos satu API:

  • Dekripsi(XElement encryptedElement) : XElement

Metode Decrypt membatalkan enkripsi yang dilakukan oleh IXmlEncryptor.Encrypt. Umumnya, setiap implementasi konkret IXmlEncryptor akan memiliki implementasi konkret IXmlDecryptor yang sesuai.

Jenis yang mengimplementasikan IXmlDecryptor harus memiliki salah satu dari dua konstruktor publik berikut:

  • .ctor(IServiceProvider)
  • .ctor()

Catatan

Yang IServiceProvider diteruskan ke konstruktor mungkin null.

IKeyEscrowSink

Antarmuka IKeyEscrowSink mewakili jenis yang dapat melakukan escrow informasi sensitif. Ingat bahwa deskriptor berseri mungkin berisi informasi sensitif (seperti materi kriptografi), dan inilah yang menyebabkan pengenalan jenis IXmlEncryptor di tempat pertama. Namun, kecelakaan terjadi, dan cincin kunci dapat dihapus atau rusak.

Antarmuka escrow menyediakan penetasan escape darurat, memungkinkan akses ke XML berseri mentah sebelum diubah oleh IXmlEncryptor yang dikonfigurasi. Antarmuka mengekspos satu API:

  • Store(Guid keyId, elemen XElement)

Terserah implementasi untuk IKeyEscrowSink menangani elemen yang disediakan dengan cara yang aman konsisten dengan kebijakan bisnis. Salah satu implementasi yang mungkin bisa untuk sink escrow untuk mengenkripsi elemen XML menggunakan sertifikat X.509 perusahaan yang diketahui di mana kunci privat sertifikat telah diekskrow; jenis dapat CertificateXmlEncryptor membantu dengan ini. Implementasi IKeyEscrowSink ini juga bertanggung jawab untuk mempertahankan elemen yang disediakan dengan tepat.

Secara default tidak ada mekanisme escrow yang diaktifkan, meskipun administrator server dapat mengonfigurasi ini secara global. Ini juga dapat dikonfigurasi secara terprogram melalui metode seperti yang IDataProtectionBuilder.AddKeyEscrowSink ditunjukkan pada sampel di bawah ini. Metode ini AddKeyEscrowSink mencerminkan IServiceCollection.AddSingleton kelebihan beban dan IServiceCollection.AddInstance , karena IKeyEscrowSink instans dimaksudkan untuk menjadi singleton. Jika beberapa IKeyEscrowSink instans terdaftar, masing-masing akan dipanggil selama pembuatan kunci, sehingga kunci dapat diekskrow ke beberapa mekanisme secara bersamaan.

Tidak ada API untuk membaca materi dari IKeyEscrowSink instans. Ini konsisten dengan teori desain mekanisme escrow: ini dimaksudkan untuk membuat materi kunci dapat diakses oleh otoritas tepercaya, dan karena aplikasi itu sendiri bukan otoritas tepercaya, itu seharusnya tidak memiliki akses ke materi escrowed sendiri.

Kode sampel berikut menunjukkan pembuatan dan pendaftaran IKeyEscrowSink di mana kunci diekstrak sedemikian sehingga hanya anggota "Admin CONTOSODomain" yang dapat memulihkannya.

Catatan

Untuk menjalankan sampel ini, Anda harus berada di komputer Windows 8 / Windows Server 2012 yang bergabung dengan domain, dan pengendali domain harus Windows Server 2012 atau yang lebih baru.

using System;
using System.IO;
using System.Xml.Linq;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddDataProtection()
            .PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys"))
            .ProtectKeysWithDpapi()
            .AddKeyEscrowSink(sp => new MyKeyEscrowSink(sp));
        var services = serviceCollection.BuildServiceProvider();

        // get a reference to the key manager and force a new key to be generated
        Console.WriteLine("Generating new key...");
        var keyManager = services.GetService<IKeyManager>();
        keyManager.CreateNewKey(
            activationDate: DateTimeOffset.Now,
            expirationDate: DateTimeOffset.Now.AddDays(7));
    }

    // A key escrow sink where keys are escrowed such that they
    // can be read by members of the CONTOSO\Domain Admins group.
    private class MyKeyEscrowSink : IKeyEscrowSink
    {
        private readonly IXmlEncryptor _escrowEncryptor;

        public MyKeyEscrowSink(IServiceProvider services)
        {
            // Assuming I'm on a machine that's a member of the CONTOSO
            // domain, I can use the Domain Admins SID to generate an
            // encrypted payload that only they can read. Sample SID from
            // https://technet.microsoft.com/library/cc778824(v=ws.10).aspx.
            _escrowEncryptor = new DpapiNGXmlEncryptor(
                "SID=S-1-5-21-1004336348-1177238915-682003330-512",
                DpapiNGProtectionDescriptorFlags.None,
                new LoggerFactory());
        }

        public void Store(Guid keyId, XElement element)
        {
            // Encrypt the key element to the escrow encryptor.
            var encryptedXmlInfo = _escrowEncryptor.Encrypt(element);

            // A real implementation would save the escrowed key to a
            // write-only file share or some other stable storage, but
            // in this sample we'll just write it out to the console.
            Console.WriteLine($"Escrowing key {keyId}");
            Console.WriteLine(encryptedXmlInfo.EncryptedElement);

            // Note: We cannot read the escrowed key material ourselves.
            // We need to get a member of CONTOSO\Domain Admins to read
            // it for us in the event we need to recover it.
        }
    }
}

/*
 * SAMPLE OUTPUT
 *
 * Generating new key...
 * Escrowing key 38e74534-c1b8-4b43-aea1-79e856a822e5
 * <encryptedKey>
 *   <!-- This key is encrypted with Windows DPAPI-NG. -->
 *   <!-- Rule: SID=S-1-5-21-1004336348-1177238915-682003330-512 -->
 *   <value>MIIIfAYJKoZIhvcNAQcDoIIIbTCCCGkCAQ...T5rA4g==</value>
 * </encryptedKey>
 */