Bagikan melalui


Ekstensibilitas kriptografi inti di ASP.NET Core

Peringatan

Jenis yang mengimplementasikan salah satu antarmuka berikut harus aman untuk beberapa penelepon.

IAuthenticatedEncryptor

Antarmuka IAuthenticatedEncryptor adalah blok penyusun dasar subsistem kriptografi. Umumnya ada satu IAuthenticatedEncryptor per kunci, dan instans IAuthenticatedEncryptor membungkus semua materi kunci kriptografi dan informasi algoritma yang diperlukan untuk melakukan operasi kriptografi.

Seperti namanya, jenis ini bertanggung jawab untuk menyediakan layanan enkripsi dan dekripsi terautentikasi. Ini mengekspos dua API berikut.

  • Decrypt(ArraySegment<byte> ciphertext, ArraySegment<byte> additionalAuthenticatedData) : byte[]

  • Encrypt(ArraySegment<byte> plaintext, ArraySegment<byte> additionalAuthenticatedData) : byte[]

Metode Enkripsi mengembalikan blob yang menyertakan teks biasa yang disandikan dan tag autentikasi. Tag autentikasi harus mencakup data terautentikasi tambahan (AAD), meskipun AAD itu sendiri tidak perlu dipulihkan dari payload akhir. Metode Dekripsi memvalidasi tag autentikasi dan mengembalikan payload yang diurai. Semua kegagalan (kecuali ArgumentNullException dan sejenisnya) harus homogen terhadap CryptographicException.

Catatan

Instans IAuthenticatedEncryptor sendiri sebenarnya tidak perlu berisi materi kunci. Misalnya, implementasi dapat mendelegasikan ke HSM untuk semua operasi.

Cara membuat IAuthenticatedEncryptor

Antarmuka IAuthenticatedEncryptorFactory mewakili jenis yang tahu cara membuat instans IAuthenticatedEncryptor . API-nya adalah sebagai berikut.

  • CreateEncryptorInstance(kunci IKey) : IAuthenticatedEncryptor

Untuk instans IKey tertentu, setiap enkripsi terautentikasi yang dibuat oleh metode CreateEncryptorInstance harus dianggap setara, seperti dalam sampel kode di bawah ini.

// we have an IAuthenticatedEncryptorFactory instance and an IKey instance
IAuthenticatedEncryptorFactory factory = ...;
IKey key = ...;

// get an encryptor instance and perform an authenticated encryption operation
ArraySegment<byte> plaintext = new ArraySegment<byte>(Encoding.UTF8.GetBytes("plaintext"));
ArraySegment<byte> aad = new ArraySegment<byte>(Encoding.UTF8.GetBytes("AAD"));
var encryptor1 = factory.CreateEncryptorInstance(key);
byte[] ciphertext = encryptor1.Encrypt(plaintext, aad);

// get another encryptor instance and perform an authenticated decryption operation
var encryptor2 = factory.CreateEncryptorInstance(key);
byte[] roundTripped = encryptor2.Decrypt(new ArraySegment<byte>(ciphertext), aad);


// the 'roundTripped' and 'plaintext' buffers should be equivalent

IAuthenticatedEncryptorDescriptor (hanya ASP.NET Core 2.x)

Antarmuka IAuthenticatedEncryptorDescriptor mewakili jenis yang tahu cara mengekspor dirinya ke XML. API-nya adalah sebagai berikut.

  • ExportToXml() : XmlSerializedDescriptorInfo

Serialisasi XML

Perbedaan utama antara IAuthenticatedEncryptor dan IAuthenticatedEncryptorDescriptor adalah bahwa deskriptor tahu cara membuat enkripsi dan menyediakannya dengan argumen yang valid. Pertimbangkan IAuthenticatedEncryptor yang implementasinya bergantung pada SymmetricAlgorithm dan KeyedHashAlgorithm. Tugas enkripsi adalah mengonsumsi jenis ini, tetapi tidak selalu tahu dari mana jenis ini berasal, sehingga tidak dapat benar-benar menulis deskripsi yang tepat tentang cara membuat ulang dirinya sendiri jika aplikasi dimulai ulang. Deskriptor bertindak sebagai tingkat yang lebih tinggi di atas ini. Karena deskriptor tahu cara membuat instans enkripsi (misalnya, ia tahu cara membuat algoritma yang diperlukan), deskriptor dapat menserialisasikan pengetahuan tersebut dalam bentuk XML sehingga instans enkripsi dapat dibuat ulang setelah reset aplikasi.

Deskriptor dapat diserialisasikan melalui rutinitas ExportToXml-nya. Rutinitas ini mengembalikan XmlSerializedDescriptorInfo yang berisi dua properti: representasi XElement dari deskriptor dan Jenis yang mewakili IAuthenticatedEncryptorDescriptorDeserializer yang dapat digunakan untuk memunculkan kembali deskriptor ini mengingat XElement yang sesuai.

Deskriptor berseri mungkin berisi informasi sensitif seperti materi kunci kriptografi. Sistem perlindungan data memiliki dukungan bawaan untuk mengenkripsi informasi sebelum disimpan ke penyimpanan. Untuk memanfaatkan ini, deskriptor harus menandai elemen yang berisi informasi sensitif dengan nama atribut "requiresEncryption" (xmlns "<http://schemas.asp.net/2015/03/dataProtection>"), nilai "true".

Tip

Ada API pembantu untuk mengatur atribut ini. Panggil metode ekstensi XElement.MarkAsRequiresEncryption() yang terletak di namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.

Mungkin juga ada kasus di mana deskriptor berseri tidak berisi informasi sensitif. Pertimbangkan lagi kasus kunci kriptografi yang disimpan dalam HSM. Deskriptor tidak dapat menuliskan materi kunci saat menserialisasikan dirinya sendiri karena HSM tidak akan mengekspos materi dalam bentuk teks biasa. Sebagai gantinya, deskriptor mungkin menuliskan versi kunci yang dibungkus kunci (jika HSM memungkinkan ekspor dengan cara ini) atau pengidentifikasi unik HSM sendiri untuk kunci tersebut.

IAuthenticatedEncryptorDescriptorDeserializer

Antarmuka IAuthenticatedEncryptorDescriptorDeserializer mewakili jenis yang tahu cara mendeserialisasi instans IAuthenticatedEncryptorDescriptor dari XElement. Ini mengekspos satu metode:

  • ImportFromXml(elemen XElement) : IAuthenticatedEncryptorDescriptor

Metode ImportFromXml mengambil XElement yang dikembalikan oleh IAuthenticatedEncryptorDescriptor.ExportToXml dan membuat yang setara dengan IAuthenticatedEncryptorDescriptor asli.

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

  • .ctor(IServiceProvider)

  • .ctor()

Catatan

IServiceProvider yang diteruskan ke konstruktor mungkin null.

Pabrik tingkat atas

Kelas AlgorithmConfiguration mewakili jenis yang tahu cara membuat instans IAuthenticatedEncryptorDescriptor . Ini mengekspos satu API.

  • CreateNewDescriptor() : IAuthenticatedEncryptorDescriptor

Pikirkan AlgoritmaKonfigurasi sebagai pabrik tingkat atas. Konfigurasi berfungsi sebagai templat. Ini membungkus informasi algoritma (misalnya, konfigurasi ini menghasilkan deskriptor dengan kunci master AES-128-GCM), tetapi belum terkait dengan kunci tertentu.

Ketika CreateNewDescriptor dipanggil, materi kunci baru dibuat hanya untuk panggilan ini, dan IAuthenticatedEncryptorDescriptor baru diproduksi yang membungkus materi kunci ini dan informasi algoritma yang diperlukan untuk mengonsumsi materi. Materi kunci dapat dibuat dalam perangkat lunak (dan disimpan dalam memori), dapat dibuat dan disimpan dalam HSM, dan sebagainya. Poin pentingnya adalah bahwa dua panggilan ke CreateNewDescriptor tidak boleh membuat instans IAuthenticatedEncryptorDescriptor yang setara.

Jenis AlgoritmaConfiguration berfungsi sebagai titik masuk untuk rutinitas pembuatan kunci seperti rolling kunci otomatis. Untuk mengubah implementasi untuk semua kunci di masa mendatang, atur properti AuthenticatedEncryptorConfiguration di KeyManagementOptions.