Bagikan melalui


Derivasi subkunjung dan enkripsi terautentikasi di ASP.NET Core

Sebagian besar kunci dalam cincin kunci akan berisi beberapa bentuk entropi dan akan memiliki informasi algoritma yang menyatakan "enkripsi mode CBC + validasi HMAC" atau "enkripsi + validasi GCM". Dalam kasus ini, kami merujuk pada entropi yang disematkan sebagai materi keying master (atau KM) untuk kunci ini, dan kami melakukan fungsi derivasi utama untuk mendapatkan kunci yang akan digunakan untuk operasi kriptografi aktual.

Catatan

Kunci bersifat abstrak, dan implementasi kustom mungkin tidak bertingkah seperti di bawah ini. Jika kunci menyediakan implementasinya sendiri daripada IAuthenticatedEncryptor menggunakan salah satu pabrik bawaan kami, mekanisme yang dijelaskan di bagian ini tidak lagi berlaku.

Data tambahan yang diautentikasi dan derivasi subkunia

Antarmuka IAuthenticatedEncryptor berfungsi sebagai antarmuka inti untuk semua operasi enkripsi terautentikasi. Metodenya Encrypt mengambil dua buffer: plaintext dan additionalAuthenticatedData (AAD). Konten teks biasa mengalir tidak mengubah panggilan ke IDataProtector.Protect, tetapi AAD dihasilkan oleh sistem dan terdiri dari tiga komponen:

  1. Header ajaib 32-bit 09 F0 C9 F0 yang mengidentifikasi versi sistem perlindungan data ini.

  2. Id kunci 128-bit.

  3. String panjang variabel yang terbentuk dari rantai tujuan yang membuat IDataProtector yang melakukan operasi ini.

Karena AAD unik untuk tuple ketiga komponen, kita dapat menggunakannya untuk mendapatkan kunci baru dari KM alih-alih menggunakan KM itu sendiri di semua operasi kriptografi kita. Untuk setiap panggilan ke IAuthenticatedEncryptor.Encrypt, proses derivasi kunci berikut terjadi:

( K_E, K_H ) = SP800_108_CTR_HMACSHA512(K_M, AAD, contextHeader || keyModifier)

Di sini, kami memanggil NIST SP800-108 KDF dalam Mode Penghitung (lihat NIST SP800-108, Sec. 5.1) dengan parameter berikut:

  • Kunci derivasi kunci (KDK) = K_M

  • PRF = HMACSHA512

  • label = additionalAuthenticatedData

  • konteks = contextHeader || keyModifier

Header konteks memiliki panjang variabel dan pada dasarnya berfungsi sebagai thumbprint algoritma yang kami turunkan K_E dan K_H. Pengubah kunci adalah string 128-bit yang dihasilkan secara acak untuk setiap panggilan ke Encrypt dan berfungsi untuk memastikan dengan probabilitas yang luar biasa bahwa KE dan KH unik untuk operasi enkripsi autentikasi khusus ini, bahkan jika semua input lain ke KDF konstan.

Untuk enkripsi mode CBC + operasi validasi HMAC, | K_E | adalah panjang kunci cipher blok simetris, dan | K_H | merupakan ukuran hash dari rutinitas HMAC. Untuk enkripsi GCM + operasi validasi, | K_H | = 0.

Enkripsi mode CBC + validasi HMAC

Setelah K_E dihasilkan melalui mekanisme di atas, kami menghasilkan vektor inisialisasi acak dan menjalankan algoritma sandi blok simetris untuk mengolah teks biasa. Vektor inisialisasi dan ciphertext kemudian dijalankan melalui rutinitas HMAC yang diinisialisasi dengan kunci K_H untuk menghasilkan MAC. Proses ini dan nilai pengembalian diwakili secara grafis di bawah ini.

CBC-mode process and return

output:= keyModifier || iv || E_cbc (K_E,iv,data) || HMAC(K_H, iv || E_cbc (K_E,iv,data))

Catatan

Implementasi IDataProtector.Protect akan menambahkan header ajaib dan id kunci ke output sebelum mengembalikannya ke pemanggil. Karena header ajaib dan id kunci secara implisit merupakan bagian dari AAD, dan karena pengubah kunci diumpankan sebagai input ke KDF, ini berarti bahwa setiap byte tunggal dari payload yang dikembalikan akhir diautentikasi oleh MAC.

Enkripsi Galois/Mode Penghitung + validasi

Setelah K_E dihasilkan melalui mekanisme di atas, kami menghasilkan nonce 96-bit acak dan menjalankan algoritma sandi blok simetris untuk mengolah teks biasa dan menghasilkan tag autentikasi 128-bit.

GCM-mode process and return

output := keyModifier || nonce || E_gcm (K_E,nonce,data) || authTag

Catatan

Meskipun GCM secara asli mendukung konsep AAD, kami masih memberi umpan AAD hanya ke KDF asli, memilih untuk meneruskan string kosong ke GCM untuk parameter AAD-nya. Alasan untuk ini adalah dua kali lipat. Pertama, untuk mendukung kelincahan , kami tidak pernah ingin menggunakan K_M langsung sebagai kunci enkripsi. Selain itu, GCM memberlakukan persyaratan keunikan yang sangat ketat pada inputnya. Probabilitas bahwa rutinitas enkripsi GCM pernah dipanggil pada dua set data input yang berbeda atau lebih dengan pasangan (kunci, nonce) yang sama tidak boleh melebihi 2^-32. Jika kami memperbaiki K_E , kami tidak dapat melakukan lebih dari 2^32 operasi enkripsi sebelum kami menjalankan afoul batas 2^-32. Ini mungkin tampak seperti sejumlah besar operasi, tetapi server web dengan lalu lintas tinggi dapat melalui 4 miliar permintaan hanya dalam beberapa hari, baik dalam masa pakai normal untuk kunci ini. Untuk tetap mematuhi batas probabilitas 2^-32, kami terus menggunakan pengubah kunci 128-bit dan nonce 96-bit, yang secara radikal memperluas jumlah operasi yang dapat digunakan untuk apa pun yang diberikan K_M. Untuk kesederhanaan desain, kami berbagi jalur kode KDF antara operasi CBC dan GCM, dan karena AAD sudah dipertimbangkan di KDF tidak perlu meneruskannya ke rutinitas GCM.